]> granicus.if.org Git - vim/commitdiff
patch 8.1.1752: resizing hashtable is inefficient v8.1.1752
authorBram Moolenaar <Bram@vim.org>
Fri, 26 Jul 2019 19:26:34 +0000 (21:26 +0200)
committerBram Moolenaar <Bram@vim.org>
Fri, 26 Jul 2019 19:26:34 +0000 (21:26 +0200)
Problem:    Resizing hashtable is inefficient.
Solution:   Avoid resizing when the final size is predictable.

src/hashtab.c
src/popupwin.c
src/proto/hashtab.pro
src/version.c

index ad018578b602ee5817d3ecf87f49c48b9198b9b2..450cf98f53d8efffbd160201f6c0474ebf5d37c0 100644 (file)
@@ -286,7 +286,6 @@ hash_lock(hashtab_T *ht)
     ++ht->ht_locked;
 }
 
-#if 0      /* currently not used */
 /*
  * Lock a hashtable at the specified number of entries.
  * Caller must make sure no more than "size" entries will be added.
@@ -298,7 +297,6 @@ hash_lock_size(hashtab_T *ht, int size)
     (void)hash_may_resize(ht, size);
     ++ht->ht_locked;
 }
-#endif
 
 /*
  * Unlock a hashtable: allow ht_array changes again.
@@ -368,10 +366,10 @@ hash_may_resize(
     }
     else
     {
-       /* Use specified size. */
-       if ((long_u)minitems < ht->ht_used)     /* just in case... */
+       // Use specified size.
+       if ((long_u)minitems < ht->ht_used)     // just in case...
            minitems = (int)ht->ht_used;
-       minsize = minitems * 3 / 2;     /* array is up to 2/3 full */
+       minsize = (minitems * 3 + 1) / 2;       // array is up to 2/3 full
     }
 
     newsize = HT_INIT_SIZE;
index d0f6156adf8fcd61d89b8fef15de9cccb7da1bc8..4750adf214d7f045a74f1d4a17aee000265eea8f 100644 (file)
@@ -2032,7 +2032,9 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
        top_extra = popup_top_extra(wp);
        left_extra = wp->w_popup_border[3] + wp->w_popup_padding[3];
 
+       // we know how much space we need, avoid resizing halfway
        dict = rettv->vval.v_dict;
+       hash_lock_size(&dict->dv_hashtab, 11);
 
        dict_add_number(dict, "line", wp->w_winrow + 1);
        dict_add_number(dict, "col", wp->w_wincol + 1);
@@ -2050,6 +2052,8 @@ f_popup_getpos(typval_T *argvars, typval_T *rettv)
        dict_add_number(dict, "firstline", wp->w_topline);
        dict_add_number(dict, "visible",
                      win_valid(wp) && (wp->w_popup_flags & POPF_HIDDEN) == 0);
+
+       hash_unlock(&dict->dv_hashtab);
     }
 }
 /*
index 96907147d1af366eee6b8b7de52d0f491ae375c1..21794ed6fda4c89734bde32bb0606ba1d45ab940 100644 (file)
@@ -9,6 +9,7 @@ int hash_add(hashtab_T *ht, char_u *key);
 int hash_add_item(hashtab_T *ht, hashitem_T *hi, char_u *key, hash_T hash);
 void hash_remove(hashtab_T *ht, hashitem_T *hi);
 void hash_lock(hashtab_T *ht);
+void hash_lock_size(hashtab_T *ht, int size);
 void hash_unlock(hashtab_T *ht);
 hash_T hash_hash(char_u *key);
 /* vim: set ft=c : */
index 5104f6a992b857f2de140098d741e8e13b978781..25bfd1679fa296017353146da33f68a8bd540e0a 100644 (file)
@@ -777,6 +777,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    1752,
 /**/
     1751,
 /**/