significantly improve performance on large strings - dmenu - dynamic menu | |
git clone git://git.suckless.org/dmenu | |
Log | |
Files | |
Refs | |
README | |
LICENSE | |
--- | |
commit 7269c5355d257dd2ad2c53f15dc9c1cf6796aea5 | |
parent 6be057f060543bb0f3ed9423904263617cdffffe | |
Author: NRK <[email protected]> | |
Date: Thu, 24 Mar 2022 02:04:04 +0600 | |
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. | |
Diffstat: | |
M dmenu.c | 13 ++++++++++--- | |
1 file changed, 10 insertions(+), 3 deletions(-) | |
--- | |
diff --git a/dmenu.c b/dmenu.c | |
@@ -58,6 +58,13 @@ static Clr *scheme[SchemeLast]; | |
static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; | |
static char *(*fstrstr)(const char *, const char *) = strstr; | |
+static unsigned int | |
+textw_clamp(const char *str, unsigned int n) | |
+{ | |
+ unsigned int w = drw_fontset_getwidth_clamp(drw, str, n) + lrpad; | |
+ return MIN(w, n); | |
+} | |
+ | |
static void | |
appenditem(struct item *item, struct item **list, struct item **last) | |
{ | |
@@ -82,10 +89,10 @@ calcoffsets(void) | |
n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">")); | |
/* calculate which items will begin the next page and previous page */ | |
for (i = 0, next = curr; next; next = next->right) | |
- if ((i += (lines > 0) ? bh : MIN(TEXTW(next->text), n)) > n) | |
+ if ((i += (lines > 0) ? bh : textw_clamp(next->text, n)) > n) | |
break; | |
for (i = 0, prev = curr; prev && prev->left; prev = prev->left) | |
- if ((i += (lines > 0) ? bh : MIN(TEXTW(prev->left->text), n)) … | |
+ if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n))… | |
break; | |
} | |
@@ -172,7 +179,7 @@ drawmenu(void) | |
} | |
x += w; | |
for (item = curr; item != next; item = item->right) | |
- x = drawitem(item, x, 0, MIN(TEXTW(item->text), mw - x… | |
+ x = drawitem(item, x, 0, textw_clamp(item->text, mw - … | |
if (next) { | |
w = TEXTW(">"); | |
drw_setscheme(drw, scheme[SchemeNorm]); |