diff options
| author | Mattias EngdegÄrd | 2024-01-15 10:58:59 +0100 |
|---|---|---|
| committer | Mattias EngdegÄrd | 2024-01-16 20:34:43 +0100 |
| commit | dc404c5d0caac798627751bfd77ed005629abd4e (patch) | |
| tree | d64c48a544524c82c7745fc51eacece9d83824b0 | |
| parent | 0b8fe3c73ce4e9a2a8f025655970e86e0d81a0aa (diff) | |
| download | emacs-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.c | 52 |
1 files changed, 31 insertions, 21 deletions
| @@ -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 | ||