diff options
author | NRK <nrk@disroot.org> | 2022-03-24 02:04:04 +0600 |
---|---|---|
committer | Hiltjo Posthuma <hiltjo@codemadness.org> | 2022-03-25 22:49:07 +0100 |
commit | 7269c5355d257dd2ad2c53f15dc9c1cf6796aea5 (patch) | |
tree | f043c06fb58bc7a161c9329c48ec98759d9cc401 | |
parent | 6be057f060543bb0f3ed9423904263617cdffffe (diff) |
significantly improve performance on large strings
this replaces inefficient pattern of `MIN(TEXTW(..), n)` with
drw_fontset_getwidth_clamp() instead, which is far more efficient when
we only want up to a certain width.
dumping a decently sized (unicode) emoji file into dmenu, I see the
startup time drop significantly with this patch.
before -> after
360ms -> 160ms
this should also noticeably improve input latency (responsiveness) given
that calcoffsets() and drawmenu() are pretty hot functions.
-rw-r--r-- | dmenu.c | 13 |
1 files changed, 10 insertions, 3 deletions
@@ -58,6 +58,13 @@ static Clr *scheme[SchemeLast]; | |||
58 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | 58 | static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; |
59 | static char *(*fstrstr)(const char *, const char *) = strstr; | 59 | static char *(*fstrstr)(const char *, const char *) = strstr; |
60 | 60 | ||
61 | static unsigned int | ||
62 | textw_clamp(const char *str, unsigned int n) | ||
63 | { | ||
64 | unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad; | ||
65 | return MIN(w, n); | ||
66 | } | ||
67 | |||
61 | static void | 68 | static void |
62 | appenditem(struct item *item, struct item **list, struct item **last) | 69 | appenditem(struct item *item, struct item **list, struct item **last) |
63 | { | 70 | { |
@@ -82,10 +89,10 @@ calcoffsets(void) | |||
82 | n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); | 89 | n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); |
83 | /* calculate which items will begin the next page and previous page */ | 90 | /* calculate which items will begin the next page and previous page */ |
84 | for (i = 0, next = curr; next; next = next->right) | 91 | for (i = 0, next = curr; next; next = next->right) |
85 | if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) | 92 | if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) |
86 | break; | 93 | break; |
87 | for (i = 0, prev = curr; prev && prev->left; prev = prev->left) | 94 | for (i = 0, prev = curr; prev && prev->left; prev = prev->left) |
88 | if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) > n) | 95 | if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > n) |
89 | break; | 96 | break; |
90 | } | 97 | } |
91 | 98 | ||
@@ -172,7 +179,7 @@ drawmenu(void) | |||
172 | } | 179 | } |
173 | x += w; | 180 | x += w; |
174 | for (item = curr; item != next; item = item->right) | 181 | for (item = curr; item != next; item = item->right) |
175 | x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x - TEXTW(">"))); | 182 | x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); |
176 | if (next) { | 183 | if (next) { |
177 | w = TEXTW(">"); | 184 | w = TEXTW(">"); |
178 | drw_setscheme(drw, scheme[SchemeNorm]); | 185 | drw_setscheme(drw, scheme[SchemeNorm]); |