aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias EngdegÄrd2024-01-15 10:58:59 +0100
committerMattias EngdegÄrd2024-01-16 20:34:43 +0100
commitdc404c5d0caac798627751bfd77ed005629abd4e (patch)
treed64c48a544524c82c7745fc51eacece9d83824b0
parent0b8fe3c73ce4e9a2a8f025655970e86e0d81a0aa (diff)
downloademacs-dc404c5d0caac798627751bfd77ed005629abd4e.tar.gz
emacs-dc404c5d0caac798627751bfd77ed005629abd4e.zip
More efficient hash table thawing
* src/fns.c (hash_table_thaw): Don't allocate anything for empty tables. Don't initialise the next vector twice. (maybe_resize_hash_table): Factor out min_size constant.
-rw-r--r--src/fns.c52
1 files changed, 31 insertions, 21 deletions
diff --git a/src/fns.c b/src/fns.c
index acfedbfa922..5bedf49ef36 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -4665,11 +4665,12 @@ maybe_resize_hash_table (struct Lisp_Hash_Table *h)
4665 if (h->next_free < 0) 4665 if (h->next_free < 0)
4666 { 4666 {
4667 ptrdiff_t old_size = HASH_TABLE_SIZE (h); 4667 ptrdiff_t old_size = HASH_TABLE_SIZE (h);
4668 ptrdiff_t base_size = min (max (old_size, 8), PTRDIFF_MAX / 2); 4668 ptrdiff_t min_size = 8;
4669 ptrdiff_t base_size = min (max (old_size, min_size), PTRDIFF_MAX / 2);
4669 /* Grow aggressively at small sizes, then just double. */ 4670 /* Grow aggressively at small sizes, then just double. */
4670 ptrdiff_t new_size = 4671 ptrdiff_t new_size =
4671 old_size == 0 4672 old_size == 0
4672 ? 8 4673 ? min_size
4673 : (base_size <= 64 ? base_size * 4 : base_size * 2); 4674 : (base_size <= 64 ? base_size * 4 : base_size * 2);
4674 4675
4675 /* Allocate all the new vectors before updating *H, to 4676 /* Allocate all the new vectors before updating *H, to
@@ -4754,30 +4755,39 @@ hash_table_thaw (Lisp_Object hash_table)
4754 h->test = hash_table_test_from_std (h->frozen_test); 4755 h->test = hash_table_test_from_std (h->frozen_test);
4755 ptrdiff_t size = h->count; 4756 ptrdiff_t size = h->count;
4756 h->table_size = size; 4757 h->table_size = size;
4757 ptrdiff_t index_size = hash_index_size (size);
4758 h->index_size = index_size;
4759 h->next_free = -1; 4758 h->next_free = -1;
4760 4759
4761 h->hash = hash_table_alloc_bytes (size * sizeof *h->hash); 4760 if (size == 0)
4761 {
4762 h->key_and_value = NULL;
4763 h->hash = NULL;
4764 h->next = NULL;
4765 h->index_size = 1;
4766 h->index = (hash_idx_t *)empty_hash_index_vector;
4767 }
4768 else
4769 {
4770 ptrdiff_t index_size = hash_index_size (size);
4771 h->index_size = index_size;
4762 4772
4763 h->next = hash_table_alloc_bytes (size * sizeof *h->next); 4773 h->hash = hash_table_alloc_bytes (size * sizeof *h->hash);
4764 for (ptrdiff_t i = 0; i < size; i++)
4765 h->next[i] = -1;
4766 4774
4767 h->index = hash_table_alloc_bytes (index_size * sizeof *h->index); 4775 h->next = hash_table_alloc_bytes (size * sizeof *h->next);
4768 for (ptrdiff_t i = 0; i < index_size; i++)
4769 h->index[i] = -1;
4770 4776
4771 /* Recompute the actual hash codes for each entry in the table. 4777 h->index = hash_table_alloc_bytes (index_size * sizeof *h->index);
4772 Order is still invalid. */ 4778 for (ptrdiff_t i = 0; i < index_size; i++)
4773 for (ptrdiff_t i = 0; i < size; i++) 4779 h->index[i] = -1;
4774 { 4780
4775 Lisp_Object key = HASH_KEY (h, i); 4781 /* Recompute the hash codes for each entry in the table. */
4776 hash_hash_t hash_code = hash_from_key (h, key); 4782 for (ptrdiff_t i = 0; i < size; i++)
4777 ptrdiff_t start_of_bucket = hash_index_index (h, hash_code); 4783 {
4778 set_hash_hash_slot (h, i, hash_code); 4784 Lisp_Object key = HASH_KEY (h, i);
4779 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket)); 4785 hash_hash_t hash_code = hash_from_key (h, key);
4780 set_hash_index_slot (h, start_of_bucket, i); 4786 ptrdiff_t start_of_bucket = hash_index_index (h, hash_code);
4787 set_hash_hash_slot (h, i, hash_code);
4788 set_hash_next_slot (h, i, HASH_INDEX (h, start_of_bucket));
4789 set_hash_index_slot (h, start_of_bucket, i);
4790 }
4781 } 4791 }
4782} 4792}
4783 4793