[lld][WebAssembly] Reinstate mistakenly disabled test. NFC
[llvm-project.git] / libcxx / benchmarks / unordered_set_operations.bench.cpp
blobe0030d6c473ef1f3d47cd51fae82144b04e43b88
1 #include <unordered_set>
2 #include <vector>
3 #include <functional>
4 #include <cstdint>
5 #include <cstdlib>
6 #include <cstring>
8 #include "benchmark/benchmark.h"
10 #include "ContainerBenchmarks.h"
11 #include "GenerateInput.h"
12 #include "test_macros.h"
14 using namespace ContainerBenchmarks;
16 constexpr std::size_t TestNumInputs = 1024;
18 template <class _Size>
19 inline TEST_ALWAYS_INLINE
20 _Size loadword(const void* __p) {
21 _Size __r;
22 std::memcpy(&__r, __p, sizeof(__r));
23 return __r;
26 inline TEST_ALWAYS_INLINE
27 std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) {
28 return (__val >> __shift) | (__val << (64 - __shift));
31 inline TEST_ALWAYS_INLINE
32 std::size_t hash_len_16(std::size_t __u, std::size_t __v) {
33 const std::size_t __mul = 0x9ddfea08eb382d69ULL;
34 std::size_t __a = (__u ^ __v) * __mul;
35 __a ^= (__a >> 47);
36 std::size_t __b = (__v ^ __a) * __mul;
37 __b ^= (__b >> 47);
38 __b *= __mul;
39 return __b;
43 template <std::size_t _Len>
44 inline TEST_ALWAYS_INLINE
45 std::size_t hash_len_0_to_8(const char* __s) {
46 static_assert(_Len == 4 || _Len == 8, "");
47 const uint64_t __a = loadword<uint32_t>(__s);
48 const uint64_t __b = loadword<uint32_t>(__s + _Len - 4);
49 return hash_len_16(_Len + (__a << 3), __b);
52 struct UInt32Hash {
53 UInt32Hash() = default;
54 inline TEST_ALWAYS_INLINE
55 std::size_t operator()(uint32_t data) const {
56 return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data));
60 struct UInt64Hash {
61 UInt64Hash() = default;
62 inline TEST_ALWAYS_INLINE
63 std::size_t operator()(uint64_t data) const {
64 return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
68 struct UInt128Hash {
69 UInt128Hash() = default;
70 inline TEST_ALWAYS_INLINE
71 std::size_t operator()(__uint128_t data) const {
72 const __uint128_t __mask = static_cast<std::size_t>(-1);
73 const std::size_t __a = (std::size_t)(data & __mask);
74 const std::size_t __b = (std::size_t)((data & (__mask << 64)) >> 64);
75 return hash_len_16(__a, rotate_by_at_least_1(__b + 16, 16)) ^ __b;
79 struct UInt32Hash2 {
80 UInt32Hash2() = default;
81 inline TEST_ALWAYS_INLINE
82 std::size_t operator()(uint32_t data) const {
83 const uint32_t __m = 0x5bd1e995;
84 const uint32_t __r = 24;
85 uint32_t __h = 4;
86 uint32_t __k = data;
87 __k *= __m;
88 __k ^= __k >> __r;
89 __k *= __m;
90 __h *= __m;
91 __h ^= __k;
92 __h ^= __h >> 13;
93 __h *= __m;
94 __h ^= __h >> 15;
95 return __h;
99 struct UInt64Hash2 {
100 UInt64Hash2() = default;
101 inline TEST_ALWAYS_INLINE
102 std::size_t operator()(uint64_t data) const {
103 return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data));
107 //----------------------------------------------------------------------------//
108 // BM_Hash
109 // ---------------------------------------------------------------------------//
111 template <class HashFn, class GenInputs>
112 void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) {
113 auto in = gen(st.range(0));
114 const auto end = in.data() + in.size();
115 std::size_t last_hash = 0;
116 benchmark::DoNotOptimize(&last_hash);
117 while (st.KeepRunning()) {
118 for (auto it = in.data(); it != end; ++it) {
119 benchmark::DoNotOptimize(last_hash += fn(*it));
121 benchmark::ClobberMemory();
125 BENCHMARK_CAPTURE(BM_Hash,
126 uint32_random_std_hash,
127 std::hash<uint32_t>{},
128 getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
130 BENCHMARK_CAPTURE(BM_Hash,
131 uint32_random_custom_hash,
132 UInt32Hash{},
133 getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
135 BENCHMARK_CAPTURE(BM_Hash,
136 uint32_top_std_hash,
137 std::hash<uint32_t>{},
138 getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
140 BENCHMARK_CAPTURE(BM_Hash,
141 uint32_top_custom_hash,
142 UInt32Hash{},
143 getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs);
146 //----------------------------------------------------------------------------//
147 // BM_InsertValue
148 // ---------------------------------------------------------------------------//
151 // Sorted Ascending //
152 BENCHMARK_CAPTURE(BM_InsertValue,
153 unordered_set_uint32,
154 std::unordered_set<uint32_t>{},
155 getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs);
157 BENCHMARK_CAPTURE(BM_InsertValue,
158 unordered_set_uint32_sorted,
159 std::unordered_set<uint32_t>{},
160 getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
162 // Top Bytes //
163 BENCHMARK_CAPTURE(BM_InsertValue,
164 unordered_set_top_bits_uint32,
165 std::unordered_set<uint32_t>{},
166 getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);
168 BENCHMARK_CAPTURE(BM_InsertValueRehash,
169 unordered_set_top_bits_uint32,
170 std::unordered_set<uint32_t, UInt32Hash>{},
171 getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs);
173 // String //
174 BENCHMARK_CAPTURE(BM_InsertValue,
175 unordered_set_string,
176 std::unordered_set<std::string>{},
177 getRandomStringInputs)->Arg(TestNumInputs);
179 BENCHMARK_CAPTURE(BM_InsertValueRehash,
180 unordered_set_string,
181 std::unordered_set<std::string>{},
182 getRandomStringInputs)->Arg(TestNumInputs);
184 //----------------------------------------------------------------------------//
185 // BM_Find
186 // ---------------------------------------------------------------------------//
188 // Random //
189 BENCHMARK_CAPTURE(BM_Find,
190 unordered_set_random_uint64,
191 std::unordered_set<uint64_t>{},
192 getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);
194 BENCHMARK_CAPTURE(BM_FindRehash,
195 unordered_set_random_uint64,
196 std::unordered_set<uint64_t, UInt64Hash>{},
197 getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs);
199 // Sorted //
200 BENCHMARK_CAPTURE(BM_Find,
201 unordered_set_sorted_uint64,
202 std::unordered_set<uint64_t>{},
203 getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);
205 BENCHMARK_CAPTURE(BM_FindRehash,
206 unordered_set_sorted_uint64,
207 std::unordered_set<uint64_t, UInt64Hash>{},
208 getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs);
211 // Sorted //
212 #if 1
213 BENCHMARK_CAPTURE(BM_Find,
214 unordered_set_sorted_uint128,
215 std::unordered_set<__uint128_t, UInt128Hash>{},
216 getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);
218 BENCHMARK_CAPTURE(BM_FindRehash,
219 unordered_set_sorted_uint128,
220 std::unordered_set<__uint128_t, UInt128Hash>{},
221 getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs);
222 #endif
224 // Sorted //
225 BENCHMARK_CAPTURE(BM_Find,
226 unordered_set_sorted_uint32,
227 std::unordered_set<uint32_t>{},
228 getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
230 BENCHMARK_CAPTURE(BM_FindRehash,
231 unordered_set_sorted_uint32,
232 std::unordered_set<uint32_t, UInt32Hash2>{},
233 getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs);
235 // Sorted Ascending //
236 BENCHMARK_CAPTURE(BM_Find,
237 unordered_set_sorted_large_uint64,
238 std::unordered_set<uint64_t>{},
239 getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);
241 BENCHMARK_CAPTURE(BM_FindRehash,
242 unordered_set_sorted_large_uint64,
243 std::unordered_set<uint64_t, UInt64Hash>{},
244 getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs);
247 // Top Bits //
248 BENCHMARK_CAPTURE(BM_Find,
249 unordered_set_top_bits_uint64,
250 std::unordered_set<uint64_t>{},
251 getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);
253 BENCHMARK_CAPTURE(BM_FindRehash,
254 unordered_set_top_bits_uint64,
255 std::unordered_set<uint64_t, UInt64Hash>{},
256 getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs);
258 // String //
259 BENCHMARK_CAPTURE(BM_Find,
260 unordered_set_string,
261 std::unordered_set<std::string>{},
262 getRandomStringInputs)->Arg(TestNumInputs);
264 BENCHMARK_CAPTURE(BM_FindRehash,
265 unordered_set_string,
266 std::unordered_set<std::string>{},
267 getRandomStringInputs)->Arg(TestNumInputs);
269 ///////////////////////////////////////////////////////////////////////////////
270 BENCHMARK_CAPTURE(BM_InsertDuplicate,
271 unordered_set_int,
272 std::unordered_set<int>{},
273 getRandomIntegerInputs<int>)->Arg(TestNumInputs);
274 BENCHMARK_CAPTURE(BM_InsertDuplicate,
275 unordered_set_string,
276 std::unordered_set<std::string>{},
277 getRandomStringInputs)->Arg(TestNumInputs);
279 BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
280 unordered_set_int,
281 std::unordered_set<int>{},
282 getRandomIntegerInputs<int>)->Arg(TestNumInputs);
283 BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
284 unordered_set_string,
285 std::unordered_set<std::string>{},
286 getRandomStringInputs)->Arg(TestNumInputs);
288 BENCHMARK_CAPTURE(BM_InsertDuplicate,
289 unordered_set_int_insert_arg,
290 std::unordered_set<int>{},
291 getRandomIntegerInputs<int>)->Arg(TestNumInputs);
292 BENCHMARK_CAPTURE(BM_InsertDuplicate,
293 unordered_set_string_insert_arg,
294 std::unordered_set<std::string>{},
295 getRandomStringInputs)->Arg(TestNumInputs);
297 BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
298 unordered_set_int_insert_arg,
299 std::unordered_set<int>{},
300 getRandomIntegerInputs<unsigned>)->Arg(TestNumInputs);
302 BENCHMARK_CAPTURE(BM_EmplaceDuplicate,
303 unordered_set_string_arg,
304 std::unordered_set<std::string>{},
305 getRandomCStringInputs)->Arg(TestNumInputs);
307 BENCHMARK_MAIN();