gui_mch_update_tabline in Windows gvim is quadratic in the number of tabs. This 
happens because the entire control is redrawn after every 
InsertItem/SetItem/DeleteItem message. The delay starts to get *really* 
noticeable at 60 open tabs or so (Windows 7).

Note that disabling redraws during the update is not enough - the code used 
GetTabItemRect to check if the item is present; however, this forces the tab 
control to recompute the layout after every change, which still results in 
quadratic behavior.

The attached patch fixes the issue.

-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php
diff -r 61a7c3f01088 src/gui_w48.c
--- a/src/gui_w48.c	Wed Oct 03 21:48:44 2012 +0200
+++ b/src/gui_w48.c	Wed Oct 03 22:55:56 2012 -0700
@@ -2473,13 +2473,16 @@
     tie.mask = TCIF_TEXT;
     tie.iImage = -1;
 
+    /* Disable redraws for tab updates to eliminate O(N^2) draws. */
+    SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)FALSE, 0);
+
     /* Add a label for each tab page.  They all contain the same text area. */
     for (tp = first_tabpage; tp != NULL; tp = tp->tp_next, ++nr)
     {
 	if (tp == curtab)
 	    curtabidx = nr;
 
-	if (!TabCtrl_GetItemRect(s_tabhwnd, nr, &rc))
+	if (nr >= TabCtrl_GetItemCount(s_tabhwnd))
 	{
 	    /* Add the tab */
 	    tie.pszText = "-Empty-";
@@ -2513,11 +2516,14 @@
     }
 
     /* Remove any old labels. */
-    while (TabCtrl_GetItemRect(s_tabhwnd, nr, &rc))
+    while (nr < TabCtrl_GetItemCount(s_tabhwnd))
 	TabCtrl_DeleteItem(s_tabhwnd, nr);
 
     if (TabCtrl_GetCurSel(s_tabhwnd) != curtabidx)
 	TabCtrl_SetCurSel(s_tabhwnd, curtabidx);
+
+    /* Re-enable redraws. This should trigger a repaint. */
+    SendMessage(s_tabhwnd, WM_SETREDRAW, (WPARAM)TRUE, 0);
 }
 
 /*

Raspunde prin e-mail lui