15 #include "absl/container/internal/raw_hash_set.h"
20 #include "absl/base/internal/raw_logging.h"
21 #include "absl/container/internal/hash_function_defaults.h"
22 #include "absl/strings/str_format.h"
23 #include "benchmark/benchmark.h"
27 namespace container_internal {
31 static auto GetSlots(
const C& c) -> decltype(c.slots_) {
46 *new_slot = *old_slot;
52 static auto apply(F&& f,
int64_t x) -> decltype(std::forward<F>(f)(x, x)) {
53 return std::forward<F>(f)(
x,
x);
58 template <
class F,
class K,
class V,
59 class =
typename std::enable_if<
61 decltype(std::declval<F>()(
62 std::declval<const absl::string_view&>(), std::piecewise_construct,
63 std::declval<std::tuple<K>>(),
67 return std::forward<F>(f)(
key, std::piecewise_construct,
std::move(
p.first),
75 template <
class... Ts>
78 std::pair<std::string, std::string>
pair;
82 using init_type = std::pair<std::string, std::string>;
84 template <
class allocator_type,
class...
Args>
87 *
alloc, slot,
typename slot_type::ctor(), std::forward<Args>(
args)...);
90 template <
class allocator_type>
91 static void destroy(allocator_type*
alloc, slot_type* slot) {
95 template <
class allocator_type>
96 static void transfer(allocator_type*
alloc, slot_type* new_slot,
97 slot_type* old_slot) {
102 static std::pair<std::string, std::string>&
element(slot_type* slot) {
106 template <
class F,
class...
Args>
118 struct StringEq : std::equal_to<absl::string_view> {
123 : raw_hash_set<StringPolicy, StringHash, StringEq, std::allocator<int>> {
124 using Base =
typename StringTable::raw_hash_set;
130 : raw_hash_set<IntPolicy, container_internal::hash_default_hash<int64_t>,
131 std::equal_to<int64_t>, std::allocator<int64_t>> {
132 using Base =
typename IntTable::raw_hash_set;
137 struct string_generator {
142 std::uniform_int_distribution<uint32_t> printable_ascii(0x20, 0x7E);
143 std::generate(res.begin(), res.end(), [&] { return printable_ascii(rng); });
154 std::random_device rd;
155 std::mt19937 rng(rd());
156 string_generator
gen{12};
158 std::deque<std::string>
keys;
159 while (
t.size() <
state.range(0)) {
160 auto x =
t.emplace(
gen(rng),
gen(rng));
161 if (
x.second)
keys.push_back(
x.first->first);
164 while (
state.KeepRunning()) {
166 std::deque<std::string>::const_iterator
it;
167 for (
int i = 0;
i != 90; ++
i) {
168 if (i % 10 == 0)
it =
keys.end();
176 auto x =
t.emplace(
gen(rng),
gen(rng));
178 keys.push_back(
x.first->first);
187 template <
typename Benchmark>
188 void CacheInSteadyStateArgs(
Benchmark* bm) {
190 const float max_load_factor = 0.875;
197 const size_t kNumPoints = 10;
198 for (
size_t i = 0;
i != kNumPoints; ++
i)
200 capacity * (max_load_factor + i * max_load_factor / kNumPoints) / 2));
202 BENCHMARK(BM_CacheInSteadyState)->Apply(CacheInSteadyStateArgs);
205 std::random_device rd;
206 std::mt19937 rng(rd());
207 string_generator
gen{12};
209 while (
t.size() <
state.range(0)) {
214 for (
auto it =
t.begin();
it !=
t.end(); ++
it) {
224 std::random_device rd;
225 std::mt19937 rng(rd());
227 std::uniform_int_distribution<uint64_t> dist(0, ~
uint64_t{});
229 while (
t.size() <
state.range(0)) {
230 t.emplace(dist(rng));
238 BENCHMARK(BM_CopyCtor)->Range(128, 4096);
241 std::random_device rd;
242 std::mt19937 rng(rd());
244 std::uniform_int_distribution<uint64_t> dist(0, ~
uint64_t{});
245 while (
t.size() <
state.range(0)) {
246 t.emplace(dist(rng));
255 BENCHMARK(BM_CopyAssign)->Range(128, 4096);
258 std::random_device rd;
259 std::mt19937 rng(rd());
260 std::uniform_int_distribution<uint64_t> dist(0, ~
uint64_t{});
262 const size_t desired_size =
state.range(0);
263 while (
values.size() < desired_size) {
264 values.emplace_back(dist(rng));
267 for (
auto unused :
state) {
272 BENCHMARK(BM_RangeCtor)->Range(128, 65536);
295 int reserve_size =
state.range(0);
299 state.ResumeTiming();
301 t.reserve(reserve_size);
304 BENCHMARK(BM_ReserveIntTable)->Range(128, 4096);
307 int reserve_size =
state.range(0);
311 state.ResumeTiming();
313 t.reserve(reserve_size);
316 BENCHMARK(BM_ReserveStringTable)->Range(128, 4096);
319 template <
typename CtrlIter>
327 std::array<ctrl_t, Group::kWidth>
group;
340 std::array<ctrl_t, Group::kWidth>
group;
351 std::array<ctrl_t, Group::kWidth>
group;
362 std::array<ctrl_t, Group::kWidth>
group;
370 BENCHMARK(BM_Group_CountLeadingEmptyOrDeleted);
373 std::array<ctrl_t, Group::kWidth>
group;
381 BENCHMARK(BM_Group_MatchFirstEmptyOrDeleted);
384 constexpr
size_t capacity = (1 << 20) - 1;
394 while (
state.KeepRunning()) {
396 std::vector<ctrl_t> ctrl_copy = ctrl;
397 state.ResumeTiming();
433 absl::container_internal::IntTable*
table) {