emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

scratch/hash-table-perf f2d6e2713c0 07/35: Refactor hash table vector re


From: Mattias Engdegård
Subject: scratch/hash-table-perf f2d6e2713c0 07/35: Refactor hash table vector reallocation
Date: Fri, 12 Jan 2024 10:53:23 -0500 (EST)

branch: scratch/hash-table-perf
commit f2d6e2713c08eab3acd63dc3c4733ce4639917a2
Author: Mattias Engdegård <mattiase@acm.org>
Commit: Mattias Engdegård <mattiase@acm.org>

    Refactor hash table vector reallocation
    
    * src/fns.c (larger_vecalloc): Remove.
    (larger_vector): Simplify.
    (alloc_larger_vector): New.
    (maybe_resize_hash_table): Use alloc_larger_vector as a simpler and
    faster replacement for larger_vecalloc.
---
 src/fns.c | 60 +++++++++++++++++++++++++++++-------------------------------
 1 file changed, 29 insertions(+), 31 deletions(-)

diff --git a/src/fns.c b/src/fns.c
index aeaeea7375f..42ff7930621 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4339,11 +4339,10 @@ get_key_arg (Lisp_Object key, ptrdiff_t nargs, 
Lisp_Object *args, char *used)
 /* Return a Lisp vector which has the same contents as VEC but has
    at least INCR_MIN more entries, where INCR_MIN is positive.
    If NITEMS_MAX is not -1, do not grow the vector to be any larger
-   than NITEMS_MAX.  New entries in the resulting vector are
-   uninitialized.  */
+   than NITEMS_MAX.  New entries in the resulting vector are nil.  */
 
-static Lisp_Object
-larger_vecalloc (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
+Lisp_Object
+larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
 {
   struct Lisp_Vector *v;
   ptrdiff_t incr, incr_max, old_size, new_size;
@@ -4360,23 +4359,11 @@ larger_vecalloc (Lisp_Object vec, ptrdiff_t incr_min, 
ptrdiff_t nitems_max)
   new_size = old_size + incr;
   v = allocate_vector (new_size);
   memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof 
*v->contents);
+  memclear (v->contents + old_size, (new_size - old_size) * word_size);
   XSETVECTOR (vec, v);
   return vec;
 }
 
-/* Likewise, except set new entries in the resulting vector to nil.  */
-
-Lisp_Object
-larger_vector (Lisp_Object vec, ptrdiff_t incr_min, ptrdiff_t nitems_max)
-{
-  ptrdiff_t old_size = ASIZE (vec);
-  Lisp_Object v = larger_vecalloc (vec, incr_min, nitems_max);
-  ptrdiff_t new_size = ASIZE (v);
-  memclear (XVECTOR (v)->contents + old_size,
-           (new_size - old_size) * word_size);
-  return v;
-}
-
 
 /***********************************************************************
                         Low-level Functions
@@ -4631,6 +4618,20 @@ copy_hash_table (struct Lisp_Hash_Table *h1)
 }
 
 
+/* Allocate a Lisp vector of NEW_SIZE elements.
+   Copy elements from VEC and leave the rest undefined.  */
+static Lisp_Object
+alloc_larger_vector (Lisp_Object vec, ptrdiff_t new_size)
+{
+  eassert (VECTORP (vec));
+  ptrdiff_t old_size = ASIZE (vec);
+  eassert (new_size >= old_size);
+  struct Lisp_Vector *v = allocate_vector (new_size);
+  memcpy (v->contents, XVECTOR (vec)->contents, old_size * sizeof 
*v->contents);
+  XSETVECTOR (vec, v);
+  return vec;
+}
+
 /* Compute index into the index vector from a hash value.  */
 static inline ptrdiff_t
 hash_index_index (struct Lisp_Hash_Table *h, Lisp_Object hash_code)
@@ -4666,26 +4667,23 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
        new_size = old_size + 1;
 
       /* Allocate all the new vectors before updating *H, to
-        avoid problems if memory is exhausted.  larger_vecalloc
-        finishes computing the size of the replacement vectors.  */
-      Lisp_Object next = larger_vecalloc (h->next, new_size - old_size,
-                                         new_size);
-      ptrdiff_t next_size = ASIZE (next);
-      for (ptrdiff_t i = old_size; i < next_size - 1; i++)
+        avoid problems if memory is exhausted.  */
+      Lisp_Object next = alloc_larger_vector (h->next, new_size);
+      for (ptrdiff_t i = old_size; i < new_size - 1; i++)
        ASET (next, i, make_fixnum (i + 1));
-      ASET (next, next_size - 1, make_fixnum (-1));
+      ASET (next, new_size - 1, make_fixnum (-1));
 
       /* Build the new&larger key_and_value vector, making sure the new
          fields are initialized to `unbound`.  */
       Lisp_Object key_and_value
-       = larger_vecalloc (h->key_and_value, 2 * (next_size - old_size),
-                          2 * next_size);
-      for (ptrdiff_t i = 2 * old_size; i < 2 * next_size; i++)
+       = alloc_larger_vector (h->key_and_value, 2 * new_size);
+      for (ptrdiff_t i = 2 * old_size; i < 2 * new_size; i++)
         ASET (key_and_value, i, Qunbound);
 
-      Lisp_Object hash = larger_vector (h->hash, next_size - old_size,
-                                       next_size);
-      ptrdiff_t index_size = hash_index_size (h, next_size);
+      Lisp_Object hash = alloc_larger_vector (h->hash, new_size);
+      memclear (XVECTOR (hash)->contents + old_size,
+               (new_size - old_size) * word_size);
+      ptrdiff_t index_size = hash_index_size (h, new_size);
       h->index = make_vector (index_size, make_fixnum (-1));
       h->key_and_value = key_and_value;
       h->hash = hash;
@@ -4704,7 +4702,7 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
 
 #ifdef ENABLE_CHECKING
       if (HASH_TABLE_P (Vpurify_flag) && XHASH_TABLE (Vpurify_flag) == h)
-       message ("Growing hash table to: %"pD"d", next_size);
+       message ("Growing hash table to: %"pD"d", new_size);
 #endif
     }
 }



reply via email to

[Prev in Thread] Current Thread [Next in Thread]