aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNRK <nrk@disroot.org>2022-03-24 02:04:04 +0600
committerHiltjo Posthuma <hiltjo@codemadness.org>2022-03-25 22:49:07 +0100
commit7269c5355d257dd2ad2c53f15dc9c1cf6796aea5 (patch)
treef043c06fb58bc7a161c9329c48ec98759d9cc401
parent6be057f060543bb0f3ed9423904263617cdffffe (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.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/dmenu.c b/dmenu.c
index eca67ac..cde394b 100644
--- a/dmenu.c
+++ b/dmenu.c
@@ -58,6 +58,13 @@ static Clr *scheme[SchemeLast];
58static int (*fstrncmp)(const char *, const char *, size_t) = strncmp; 58static int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
59static char *(*fstrstr)(const char *, const char *) = strstr; 59static char *(*fstrstr)(const char *, const char *) = strstr;
60 60
61static unsigned int
62textw_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
61static void 68static void
62appenditem(struct item *item, struct item **list, struct item **last) 69appenditem(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]);