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 int (*fstrncmp)(const char *, const char *, size_t) = strncmp;
 | 
				
			||||||
static char *(*fstrstr)(const char *, const char *) = strstr;
 | 
					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
 | 
					static void
 | 
				
			||||||
appenditem(struct item *item, struct item **list, struct item **last)
 | 
					appenditem(struct item *item, struct item **list, struct item **last)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
@@ -82,10 +89,10 @@ calcoffsets(void)
 | 
				
			|||||||
		n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
 | 
							n = mw - (promptw + inputw + TEXTW("<") + TEXTW(">"));
 | 
				
			||||||
	/* calculate which items will begin the next page and previous page */
 | 
						/* calculate which items will begin the next page and previous page */
 | 
				
			||||||
	for (i = 0, next = curr; next; next = next->right)
 | 
						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;
 | 
								break;
 | 
				
			||||||
	for (i = 0, prev = curr; prev && prev->left; prev = prev->left)
 | 
						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;
 | 
								break;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -172,7 +179,7 @@ drawmenu(void)
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		x += w;
 | 
							x += w;
 | 
				
			||||||
		for (item = curr; item != next; item = item->right)
 | 
							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) {
 | 
							if (next) {
 | 
				
			||||||
			w = TEXTW(">");
 | 
								w = TEXTW(">");
 | 
				
			||||||
			drw_setscheme(drw, scheme[SchemeNorm]);
 | 
								drw_setscheme(drw, scheme[SchemeNorm]);
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user