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.
This commit is contained in:
		
							
								
								
									
										13
									
								
								dmenu.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								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)) > n) | ||||
| 		if ((i += (lines > 0) ? bh : textw_clamp(prev->left->text, n)) > 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 - TEXTW(">"))); | ||||
| 			x = drawitem(item, x, 0, textw_clamp(item->text, mw - x - TEXTW(">"))); | ||||
| 		if (next) { | ||||
| 			w = TEXTW(">"); | ||||
| 			drw_setscheme(drw, scheme[SchemeNorm]); | ||||
|  | ||||
		Reference in New Issue
	
	Block a user