Skip to content

Commit 359ef8f

Browse files
committed
Merge pull request #108932 from Nazarwadim/hash_map_final_optimization
Do not zero elements and perform fast clear in `HashMap`
2 parents ef34c3d + e6bc3fa commit 359ef8f

File tree

1 file changed

+17
-14
lines changed

1 file changed

+17
-14
lines changed

core/templates/hash_map.h

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,9 @@ class HashMap : private Allocator {
181181

182182
_size = 0;
183183
static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call");
184+
184185
_hashes = reinterpret_cast<uint32_t *>(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity));
185-
_elements = reinterpret_cast<HashMapElement<TKey, TValue> **>(Memory::alloc_static_zeroed(sizeof(HashMapElement<TKey, TValue> *) * capacity));
186+
_elements = reinterpret_cast<HashMapElement<TKey, TValue> **>(Memory::alloc_static(sizeof(HashMapElement<TKey, TValue> *) * capacity));
186187

187188
if (old_capacity == 0) {
188189
// Nothing to do.
@@ -208,7 +209,7 @@ class HashMap : private Allocator {
208209

209210
static_assert(EMPTY_HASH == 0, "Assuming EMPTY_HASH = 0 for alloc_static_zeroed call");
210211
_hashes = reinterpret_cast<uint32_t *>(Memory::alloc_static_zeroed(sizeof(uint32_t) * capacity));
211-
_elements = reinterpret_cast<HashMapElement<TKey, TValue> **>(Memory::alloc_static_zeroed(sizeof(HashMapElement<TKey, TValue> *) * capacity));
212+
_elements = reinterpret_cast<HashMapElement<TKey, TValue> **>(Memory::alloc_static(sizeof(HashMapElement<TKey, TValue> *) * capacity));
212213
}
213214

214215
if (_size + 1 > MAX_OCCUPANCY * capacity) {
@@ -235,6 +236,15 @@ class HashMap : private Allocator {
235236
return elem;
236237
}
237238

239+
void _clear_data() {
240+
HashMapElement<TKey, TValue> *current = _tail_element;
241+
while (current != nullptr) {
242+
HashMapElement<TKey, TValue> *prev = current->prev;
243+
Allocator::delete_allocation(current);
244+
current = prev;
245+
}
246+
}
247+
238248
public:
239249
_FORCE_INLINE_ uint32_t get_capacity() const { return hash_table_size_primes[_capacity_idx]; }
240250
_FORCE_INLINE_ uint32_t size() const { return _size; }
@@ -249,16 +259,9 @@ class HashMap : private Allocator {
249259
if (_elements == nullptr || _size == 0) {
250260
return;
251261
}
252-
uint32_t capacity = hash_table_size_primes[_capacity_idx];
253-
for (uint32_t i = 0; i < capacity; i++) {
254-
if (_hashes[i] == EMPTY_HASH) {
255-
continue;
256-
}
257262

258-
_hashes[i] = EMPTY_HASH;
259-
Allocator::delete_allocation(_elements[i]);
260-
_elements[i] = nullptr;
261-
}
263+
_clear_data();
264+
memset(_hashes, EMPTY_HASH, get_capacity() * sizeof(uint32_t));
262265

263266
_tail_element = nullptr;
264267
_head_element = nullptr;
@@ -356,7 +359,6 @@ class HashMap : private Allocator {
356359
}
357360

358361
Allocator::delete_allocation(_elements[idx]);
359-
_elements[idx] = nullptr;
360362

361363
_size--;
362364
return true;
@@ -385,8 +387,9 @@ class HashMap : private Allocator {
385387
idx = next_idx;
386388
_increment_mod(next_idx, capacity);
387389
}
390+
388391
_hashes[idx] = EMPTY_HASH;
389-
_elements[idx] = nullptr;
392+
390393
// _insert_element will increment this again.
391394
_size--;
392395

@@ -688,7 +691,7 @@ class HashMap : private Allocator {
688691
}
689692

690693
~HashMap() {
691-
clear();
694+
_clear_data();
692695

693696
if (_elements != nullptr) {
694697
Memory::free_static(_elements);

0 commit comments

Comments
 (0)