[all-commits] [llvm/llvm-project] 3efa46: [libcxx] Avoid hash key in __hash_table::find() if...
xbcnn via All-commits
all-commits at lists.llvm.org
Thu Jul 3 00:39:32 PDT 2025
Branch: refs/heads/main
Home: https://github.com/llvm/llvm-project
Commit: 3efa461d45a1867cf03d30bd4b6caf1ed2260475
https://github.com/llvm/llvm-project/commit/3efa461d45a1867cf03d30bd4b6caf1ed2260475
Author: xbcnn <30337500+xbcnn at users.noreply.github.com>
Date: 2025-07-03 (Thu, 03 Jul 2025)
Changed paths:
M libcxx/include/__hash_table
M libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h
M libcxx/test/benchmarks/containers/associative/unordered_set.bench.cpp
Log Message:
-----------
[libcxx] Avoid hash key in __hash_table::find() if it is empty. (#126837)
If the hash table is empty, with or without buckets, the find() can do
fast return. Then computing hash key is useless and avoidable, since it
could be expensive for some key types, such as long strings.
This is a small optimization but useful in cases like a checklist
(unordered_set/map) which is mostly empty.
```
For std::unordered_set<*>, `--benchmark_filter=find`
1. With the opt:
---------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------------------------------------------
std::unordered_set<int>::find(key) (existent)/0 0.118 ns 0.118 ns 5939922720
std::unordered_set<int>::find(key) (existent)/32 52.1 ns 52.1 ns 13287232
std::unordered_set<int>::find(key) (existent)/1024 51.1 ns 51.1 ns 13449472
std::unordered_set<int>::find(key) (existent)/8192 53.1 ns 53.1 ns 13420864
std::unordered_set<int>::find(key) (non-existent)/0 14.7 ns 14.7 ns 47725472
std::unordered_set<int>::find(key) (non-existent)/32 44.1 ns 44.1 ns 15478144
std::unordered_set<int>::find(key) (non-existent)/1024 41.2 ns 41.2 ns 15082464
std::unordered_set<int>::find(key) (non-existent)/8192 49.5 ns 49.5 ns 15233600
std::unordered_set<std::string>::find(key) (existent)/0 0.136 ns 0.136 ns 5157977920
std::unordered_set<std::string>::find(key) (existent)/32 739 ns 739 ns 1023744
std::unordered_set<std::string>::find(key) (existent)/1024 836 ns 836 ns 840448
std::unordered_set<std::string>::find(key) (existent)/8192 768 ns 768 ns 1085664
std::unordered_set<std::string>::find(key) (non-existent)/0 14.6 ns 14.6 ns 47844160
std::unordered_set<std::string>::find(key) (non-existent)/32 608 ns 608 ns 1106496
std::unordered_set<std::string>::find(key) (non-existent)/1024 646 ns 646 ns 986272
std::unordered_set<std::string>::find(key) (non-existent)/8192 669 ns 669 ns 1047584
2. Without the opt:
---------------------------------------------------------------------------------------------------------
Benchmark Time CPU Iterations
---------------------------------------------------------------------------------------------------------
std::unordered_set<int>::find(key) (existent)/0 0.135 ns 0.135 ns 5188502304
std::unordered_set<int>::find(key) (existent)/32 54.4 ns 54.4 ns 12954144
std::unordered_set<int>::find(key) (existent)/1024 57.7 ns 57.7 ns 13107008
std::unordered_set<int>::find(key) (existent)/8192 50.7 ns 50.7 ns 12953312
std::unordered_set<int>::find(key) (non-existent)/0 16.1 ns 16.1 ns 43460192
std::unordered_set<int>::find(key) (non-existent)/32 45.8 ns 45.8 ns 17139584
std::unordered_set<int>::find(key) (non-existent)/1024 44.6 ns 44.6 ns 16538048
std::unordered_set<int>::find(key) (non-existent)/8192 41.5 ns 41.5 ns 12850816
std::unordered_set<std::string>::find(key) (existent)/0 0.133 ns 0.133 ns 5214104992
std::unordered_set<std::string>::find(key) (existent)/32 731 ns 731 ns 1000576
std::unordered_set<std::string>::find(key) (existent)/1024 716 ns 716 ns 1131584
std::unordered_set<std::string>::find(key) (existent)/8192 745 ns 745 ns 909632
std::unordered_set<std::string>::find(key) (non-existent)/0 600 ns 600 ns 1089792
std::unordered_set<std::string>::find(key) (non-existent)/32 645 ns 645 ns 979232
std::unordered_set<std::string>::find(key) (non-existent)/1024 675 ns 675 ns 962240
std::unordered_set<std::string>::find(key) (non-existent)/8192 711 ns 711 ns 1054880
```
We can see the improvements when find() for non-existent
`std::string`(random size 1~1024) keys:
```
std::unordered_set<std::string>::find(key) (non-existent)/0 14.6 ns 14.6 ns 47844160
std::unordered_set<std::string>::find(key) (non-existent)/0 600 ns 600 ns 1089792
```
---------
Co-authored-by: yangxiaobing <yangxiaobing at jwzg.com>
To unsubscribe from these emails, change your notification settings at https://github.com/llvm/llvm-project/settings/notifications
More information about the All-commits
mailing list