diff options
author | 2021-01-02 20:29:13 +0000 | |
---|---|---|
committer | 2021-01-02 20:29:13 +0000 | |
commit | 46035553bfdd96e63c94e32da0210227ec2e3cf1 (patch) | |
tree | b191f708fb9a2995ba745b2f31cdeeaee4872b7f /gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp | |
parent | Move Makefiles for libc++ and libc++abi to gnu/lib in preparation for an (diff) | |
download | wireguard-openbsd-46035553bfdd96e63c94e32da0210227ec2e3cf1.tar.xz wireguard-openbsd-46035553bfdd96e63c94e32da0210227ec2e3cf1.zip |
Import libc++ 10.0.1 release.
Diffstat (limited to 'gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp')
-rw-r--r-- | gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp | 307 |
1 files changed, 307 insertions, 0 deletions
diff --git a/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp b/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp new file mode 100644 index 00000000000..e0030d6c473 --- /dev/null +++ b/gnu/llvm/libcxx/benchmarks/unordered_set_operations.bench.cpp @@ -0,0 +1,307 @@ +#include <unordered_set> +#include <vector> +#include <functional> +#include <cstdint> +#include <cstdlib> +#include <cstring> + +#include "benchmark/benchmark.h" + +#include "ContainerBenchmarks.h" +#include "GenerateInput.h" +#include "test_macros.h" + +using namespace ContainerBenchmarks; + +constexpr std::size_t TestNumInputs = 1024; + +template <class _Size> +inline TEST_ALWAYS_INLINE +_Size loadword(const void* __p) { + _Size __r; + std::memcpy(&__r, __p, sizeof(__r)); + return __r; +} + +inline TEST_ALWAYS_INLINE +std::size_t rotate_by_at_least_1(std::size_t __val, int __shift) { + return (__val >> __shift) | (__val << (64 - __shift)); +} + +inline TEST_ALWAYS_INLINE +std::size_t hash_len_16(std::size_t __u, std::size_t __v) { + const std::size_t __mul = 0x9ddfea08eb382d69ULL; + std::size_t __a = (__u ^ __v) * __mul; + __a ^= (__a >> 47); + std::size_t __b = (__v ^ __a) * __mul; + __b ^= (__b >> 47); + __b *= __mul; + return __b; +} + + +template <std::size_t _Len> +inline TEST_ALWAYS_INLINE +std::size_t hash_len_0_to_8(const char* __s) { + static_assert(_Len == 4 || _Len == 8, ""); + const uint64_t __a = loadword<uint32_t>(__s); + const uint64_t __b = loadword<uint32_t>(__s + _Len - 4); + return hash_len_16(_Len + (__a << 3), __b); +} + +struct UInt32Hash { + UInt32Hash() = default; + inline TEST_ALWAYS_INLINE + std::size_t operator()(uint32_t data) const { + return hash_len_0_to_8<4>(reinterpret_cast<const char*>(&data)); + } +}; + +struct UInt64Hash { + UInt64Hash() = default; + inline TEST_ALWAYS_INLINE + std::size_t operator()(uint64_t data) const { + return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data)); + } +}; + +struct UInt128Hash { + UInt128Hash() = default; + inline TEST_ALWAYS_INLINE + std::size_t operator()(__uint128_t data) const { + const __uint128_t __mask = static_cast<std::size_t>(-1); + const std::size_t __a = (std::size_t)(data & __mask); + const std::size_t __b = (std::size_t)((data & (__mask << 64)) >> 64); + return hash_len_16(__a, rotate_by_at_least_1(__b + 16, 16)) ^ __b; + } +}; + +struct UInt32Hash2 { + UInt32Hash2() = default; + inline TEST_ALWAYS_INLINE + std::size_t operator()(uint32_t data) const { + const uint32_t __m = 0x5bd1e995; + const uint32_t __r = 24; + uint32_t __h = 4; + uint32_t __k = data; + __k *= __m; + __k ^= __k >> __r; + __k *= __m; + __h *= __m; + __h ^= __k; + __h ^= __h >> 13; + __h *= __m; + __h ^= __h >> 15; + return __h; + } +}; + +struct UInt64Hash2 { + UInt64Hash2() = default; + inline TEST_ALWAYS_INLINE + std::size_t operator()(uint64_t data) const { + return hash_len_0_to_8<8>(reinterpret_cast<const char*>(&data)); + } +}; + +//----------------------------------------------------------------------------// +// BM_Hash +// ---------------------------------------------------------------------------// + +template <class HashFn, class GenInputs> +void BM_Hash(benchmark::State& st, HashFn fn, GenInputs gen) { + auto in = gen(st.range(0)); + const auto end = in.data() + in.size(); + std::size_t last_hash = 0; + benchmark::DoNotOptimize(&last_hash); + while (st.KeepRunning()) { + for (auto it = in.data(); it != end; ++it) { + benchmark::DoNotOptimize(last_hash += fn(*it)); + } + benchmark::ClobberMemory(); + } +} + +BENCHMARK_CAPTURE(BM_Hash, + uint32_random_std_hash, + std::hash<uint32_t>{}, + getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_Hash, + uint32_random_custom_hash, + UInt32Hash{}, + getRandomIntegerInputs<uint32_t>) -> Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_Hash, + uint32_top_std_hash, + std::hash<uint32_t>{}, + getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_Hash, + uint32_top_custom_hash, + UInt32Hash{}, + getSortedTopBitsIntegerInputs<uint32_t>) -> Arg(TestNumInputs); + + +//----------------------------------------------------------------------------// +// BM_InsertValue +// ---------------------------------------------------------------------------// + + +// Sorted Ascending // +BENCHMARK_CAPTURE(BM_InsertValue, + unordered_set_uint32, + std::unordered_set<uint32_t>{}, + getRandomIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_InsertValue, + unordered_set_uint32_sorted, + std::unordered_set<uint32_t>{}, + getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +// Top Bytes // +BENCHMARK_CAPTURE(BM_InsertValue, + unordered_set_top_bits_uint32, + std::unordered_set<uint32_t>{}, + getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_InsertValueRehash, + unordered_set_top_bits_uint32, + std::unordered_set<uint32_t, UInt32Hash>{}, + getSortedTopBitsIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +// String // +BENCHMARK_CAPTURE(BM_InsertValue, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_InsertValueRehash, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +//----------------------------------------------------------------------------// +// BM_Find +// ---------------------------------------------------------------------------// + +// Random // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_random_uint64, + std::unordered_set<uint64_t>{}, + getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_random_uint64, + std::unordered_set<uint64_t, UInt64Hash>{}, + getRandomIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +// Sorted // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_sorted_uint64, + std::unordered_set<uint64_t>{}, + getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_sorted_uint64, + std::unordered_set<uint64_t, UInt64Hash>{}, + getSortedIntegerInputs<uint64_t>)->Arg(TestNumInputs); + + +// Sorted // +#if 1 +BENCHMARK_CAPTURE(BM_Find, + unordered_set_sorted_uint128, + std::unordered_set<__uint128_t, UInt128Hash>{}, + getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_sorted_uint128, + std::unordered_set<__uint128_t, UInt128Hash>{}, + getSortedTopBitsIntegerInputs<__uint128_t>)->Arg(TestNumInputs); +#endif + +// Sorted // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_sorted_uint32, + std::unordered_set<uint32_t>{}, + getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_sorted_uint32, + std::unordered_set<uint32_t, UInt32Hash2>{}, + getSortedIntegerInputs<uint32_t>)->Arg(TestNumInputs); + +// Sorted Ascending // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_sorted_large_uint64, + std::unordered_set<uint64_t>{}, + getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_sorted_large_uint64, + std::unordered_set<uint64_t, UInt64Hash>{}, + getSortedLargeIntegerInputs<uint64_t>)->Arg(TestNumInputs); + + +// Top Bits // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_top_bits_uint64, + std::unordered_set<uint64_t>{}, + getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_top_bits_uint64, + std::unordered_set<uint64_t, UInt64Hash>{}, + getSortedTopBitsIntegerInputs<uint64_t>)->Arg(TestNumInputs); + +// String // +BENCHMARK_CAPTURE(BM_Find, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_FindRehash, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +/////////////////////////////////////////////////////////////////////////////// +BENCHMARK_CAPTURE(BM_InsertDuplicate, + unordered_set_int, + std::unordered_set<int>{}, + getRandomIntegerInputs<int>)->Arg(TestNumInputs); +BENCHMARK_CAPTURE(BM_InsertDuplicate, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_EmplaceDuplicate, + unordered_set_int, + std::unordered_set<int>{}, + getRandomIntegerInputs<int>)->Arg(TestNumInputs); +BENCHMARK_CAPTURE(BM_EmplaceDuplicate, + unordered_set_string, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_InsertDuplicate, + unordered_set_int_insert_arg, + std::unordered_set<int>{}, + getRandomIntegerInputs<int>)->Arg(TestNumInputs); +BENCHMARK_CAPTURE(BM_InsertDuplicate, + unordered_set_string_insert_arg, + std::unordered_set<std::string>{}, + getRandomStringInputs)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_EmplaceDuplicate, + unordered_set_int_insert_arg, + std::unordered_set<int>{}, + getRandomIntegerInputs<unsigned>)->Arg(TestNumInputs); + +BENCHMARK_CAPTURE(BM_EmplaceDuplicate, + unordered_set_string_arg, + std::unordered_set<std::string>{}, + getRandomCStringInputs)->Arg(TestNumInputs); + +BENCHMARK_MAIN(); |