Skip to content
4 changes: 2 additions & 2 deletions libcxx/include/__hash_table
Original file line number Diff line number Diff line change
Expand Up @@ -1771,9 +1771,9 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _Key>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) {
size_t __hash = hash_function()(__k);
size_type __bc = bucket_count();
if (__bc != 0) {
size_t __hash = hash_function()(__k);
size_t __chash = std::__constrain_hash(__hash, __bc);
__next_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr) {
Expand All @@ -1792,9 +1792,9 @@ template <class _Tp, class _Hash, class _Equal, class _Alloc>
template <class _Key>
typename __hash_table<_Tp, _Hash, _Equal, _Alloc>::const_iterator
__hash_table<_Tp, _Hash, _Equal, _Alloc>::find(const _Key& __k) const {
size_t __hash = hash_function()(__k);
size_type __bc = bucket_count();
if (__bc != 0) {
size_t __hash = hash_function()(__k);
size_t __chash = std::__constrain_hash(__hash, __bc);
__next_pointer __nd = __bucket_list_[__chash];
if (__nd != nullptr) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#include <unordered_set>
#include <string>
#include <random>
#include <vector>

#include "../../GenerateInput.h"
#include "benchmark/benchmark.h"

// Generate random strings of at least 32 chars
struct LongStringGenerator {
static std::vector<std::string> cached_strings;

static void ensure_strings(size_t count) {
cached_strings.clear();

std::mt19937_64 gen(42); // Fixed seed for reproducibility
std::uniform_int_distribution<size_t> len_dist(32, 128);

cached_strings.reserve(count);
for (size_t i = 0; i < count; i++) {
std::string str(len_dist(gen), 0);
for (char& c : str) {
c = 'a' + (gen() % 26);
}
cached_strings.push_back(std::move(str));
}
}

const std::string& generate(size_t i) { return cached_strings[i]; }
};

std::vector<std::string> LongStringGenerator::cached_strings;
[[maybe_unused]] auto dummy = [] { // Pre-generate 32K strings
LongStringGenerator::ensure_strings(1 << 15);
return 0;
}();

template <class Gen>
static void BM_UnorderedSet_Find_EmptySet(benchmark::State& state, Gen g) {
const size_t lookup_count = state.range(0);
std::unordered_set<std::string> s; // Empty set

for (auto _ : state) {
for (size_t i = 0; i < lookup_count; i++) {
benchmark::DoNotOptimize(s.find(g.generate(i)));
}
}
}

template <class Gen>
static void BM_UnorderedSet_Find(benchmark::State& state, Gen g) {
const size_t lookup_count = state.range(0);
std::unordered_set<std::string> s{"hello"}; // Non-empty set

for (auto _ : state) {
for (size_t i = 0; i < lookup_count; i++) {
benchmark::DoNotOptimize(s.find(g.generate(i)));
}
}
}

BENCHMARK_CAPTURE(BM_UnorderedSet_Find_EmptySet, long_string, LongStringGenerator())
->RangeMultiplier(2)
->Range(1 << 10, 1 << 15); // Test from 1K to 32K lookups

BENCHMARK_CAPTURE(BM_UnorderedSet_Find, long_string, LongStringGenerator())
->RangeMultiplier(2)
->Range(1 << 10, 1 << 15); // Test from 1K to 32K lookups

BENCHMARK_MAIN();
Loading