blob: a8448ef5a0cfb9ce87c938451e57f5b2cfc51bef [file] [log] [blame]
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
// UNSUPPORTED: c++03, c++11, c++14, c++17, c++20
#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <functional>
#include <unordered_set>
#include <vector>
#include "benchmark/benchmark.h"
#include "ContainerBenchmarks.h"
#include "../GenerateInput.h"
#include "test_macros.h"
using namespace ContainerBenchmarks;
constexpr std::size_t TestNumInputs = 1024;
// The purpose of this hash function is to NOT be implemented as the identity function,
// which is how std::hash is implemented for smaller integral types.
struct NonIdentityScalarHash : std::hash<unsigned long long> {};
// The sole purpose of this comparator is to be used in BM_Rehash, where
// we need something slow enough to be easily noticable in benchmark results.
// The default implementation of operator== for strings seems to be a little
// too fast for that specific benchmark to reliably show a noticeable
// improvement, but unoptimized bytewise comparison fits just right.
// Early return is there just for convenience, since we only compare strings
// of equal length in BM_Rehash.
struct SlowStringEq {
SlowStringEq() = default;
inline TEST_ALWAYS_INLINE bool operator()(const std::string& lhs, const std::string& rhs) const {
if (lhs.size() != rhs.size())
return false;
bool eq = true;
for (size_t i = 0; i < lhs.size(); ++i) {
eq &= lhs[i] == rhs[i];
}
return eq;
}
};
//----------------------------------------------------------------------------//
// 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, NonIdentityScalarHash>{},
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);
// Prefixed String //
BENCHMARK_CAPTURE(
BM_InsertValue, unordered_set_prefixed_string, std::unordered_set<std::string>{}, getPrefixedRandomStringInputs)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(BM_InsertValueRehash,
unordered_set_prefixed_string,
std::unordered_set<std::string>{},
getPrefixedRandomStringInputs)
->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, NonIdentityScalarHash>{},
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, NonIdentityScalarHash>{},
getSortedIntegerInputs<uint64_t>)
->Arg(TestNumInputs);
// Sorted //
#ifndef TEST_HAS_NO_INT128
BENCHMARK_CAPTURE(BM_Find,
unordered_set_sorted_uint128,
std::unordered_set<__uint128_t>{},
getSortedTopBitsIntegerInputs<__uint128_t>)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(BM_FindRehash,
unordered_set_sorted_uint128,
std::unordered_set<__uint128_t>{},
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, NonIdentityScalarHash>{},
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, NonIdentityScalarHash>{},
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, NonIdentityScalarHash>{},
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);
// Prefixed String //
BENCHMARK_CAPTURE(
BM_Find, unordered_set_prefixed_string, std::unordered_set<std::string>{}, getPrefixedRandomStringInputs)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(
BM_FindRehash, unordered_set_prefixed_string, std::unordered_set<std::string>{}, getPrefixedRandomStringInputs)
->Arg(TestNumInputs);
//----------------------------------------------------------------------------//
// BM_Rehash
// ---------------------------------------------------------------------------//
BENCHMARK_CAPTURE(BM_Rehash,
unordered_set_string_arg,
std::unordered_set<std::string, std::hash<std::string>, SlowStringEq>{},
getRandomStringInputs)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(BM_Rehash, unordered_set_int_arg, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);
//----------------------------------------------------------------------------//
// BM_Compare
// ---------------------------------------------------------------------------//
BENCHMARK_CAPTURE(
BM_Compare_same_container, unordered_set_string, std::unordered_set<std::string>{}, getRandomStringInputs)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(BM_Compare_same_container, unordered_set_int, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(
BM_Compare_different_containers, unordered_set_string, std::unordered_set<std::string>{}, getRandomStringInputs)
->Arg(TestNumInputs);
BENCHMARK_CAPTURE(
BM_Compare_different_containers, unordered_set_int, std::unordered_set<int>{}, getRandomIntegerInputs<int>)
->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();