Skip to content

Commit b3faeac

Browse files
committed
Update associative_container_benchmarks
Removed with_expensive_key_empty and added Arg(0) to ranges. For std::unordered_set<*>, `--benchmark_filter=find` 1. With the opt: --------------------------------------------------------------------------------------------------------- Benchmark Time CPU Iterations --------------------------------------------------------------------------------------------------------- std::unordered_set<int>::find(key) (existent)/0 0.118 ns 0.118 ns 5939922720 std::unordered_set<int>::find(key) (existent)/32 52.1 ns 52.1 ns 13287232 std::unordered_set<int>::find(key) (existent)/1024 51.1 ns 51.1 ns 13449472 std::unordered_set<int>::find(key) (existent)/8192 53.1 ns 53.1 ns 13420864 std::unordered_set<int>::find(key) (non-existent)/0 14.7 ns 14.7 ns 47725472 std::unordered_set<int>::find(key) (non-existent)/32 44.1 ns 44.1 ns 15478144 std::unordered_set<int>::find(key) (non-existent)/1024 41.2 ns 41.2 ns 1508246 std::unordered_set<int>::find(key) (non-existent)/8192 49.5 ns 49.5 ns 15233600 std::unordered_set<std::string>::find(key) (existent)/0 0.136 ns 0.136 ns 5157977920 std::unordered_set<std::string>::find(key) (existent)/32 739 ns 739 ns 1023744 std::unordered_set<std::string>::find(key) (existent)/1024 836 ns 836 ns 840448 std::unordered_set<std::string>::find(key) (existent)/8192 768 ns 768 ns 1085664 std::unordered_set<std::string>::find(key) (non-existent)/0 14.6 ns 14.6 ns 47844160 std::unordered_set<std::string>::find(key) (non-existent)/32 608 ns 608 ns 1106496 std::unordered_set<std::string>::find(key) (non-existent)/1024 646 ns 646 ns 986272 std::unordered_set<std::string>::find(key) (non-existent)/8192 669 ns 669 ns 1047584 2. Without the opt: --------------------------------------------------------------------------------------------------------- Benchmark Time CPU Iterations --------------------------------------------------------------------------------------------------------- std::unordered_set<int>::find(key) (existent)/0 0.135 ns 0.135 ns 5188502304 std::unordered_set<int>::find(key) (existent)/32 54.4 ns 54.4 ns 12954144 std::unordered_set<int>::find(key) (existent)/1024 57.7 ns 57.7 ns 13107008 std::unordered_set<int>::find(key) (existent)/8192 50.7 ns 50.7 ns 12953312 std::unordered_set<int>::find(key) (non-existent)/0 16.1 ns 16.1 ns 43460192 std::unordered_set<int>::find(key) (non-existent)/32 45.8 ns 45.8 ns 17139584 std::unordered_set<int>::find(key) (non-existent)/1024 44.6 ns 44.6 ns 16538048 std::unordered_set<int>::find(key) (non-existent)/8192 41.5 ns 41.5 ns 12850816 std::unordered_set<std::string>::find(key) (existent)/0 0.133 ns 0.133 ns 5214104992 std::unordered_set<std::string>::find(key) (existent)/32 731 ns 731 ns 1000576 std::unordered_set<std::string>::find(key) (existent)/1024 716 ns 716 ns 1131584 std::unordered_set<std::string>::find(key) (existent)/8192 745 ns 745 ns 909632 std::unordered_set<std::string>::find(key) (non-existent)/0 600 ns 600 ns 1089792 std::unordered_set<std::string>::find(key) (non-existent)/32 645 ns 645 ns 979232 std::unordered_set<std::string>::find(key) (non-existent)/1024 675 ns 675 ns 962240 std::unordered_set<std::string>::find(key) (non-existent)/8192 711 ns 711 ns 1054880 We can see the difference here: std::unordered_set<std::string>::find(key) (non-existent)/0 14.6 ns 14.6 ns 47844160 std::unordered_set<std::string>::find(key) (non-existent)/0 600 ns 600 ns 1089792
1 parent 1de7487 commit b3faeac

File tree

1 file changed

+7
-33
lines changed

1 file changed

+7
-33
lines changed

libcxx/test/benchmarks/containers/associative/associative_container_benchmarks.h

Lines changed: 7 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -47,14 +47,6 @@ void associative_container_benchmarks(std::string container) {
4747
return std::vector<Key>(keys.begin(), keys.end());
4848
};
4949

50-
auto generate_expensive_keys = [=](std::size_t n) {
51-
std::vector<Key> keys;
52-
for (std::size_t i = 0; i < n; ++i) {
53-
keys.push_back(Generate<Key>::expensive());
54-
}
55-
return keys;
56-
};
57-
5850
auto make_value_types = [](std::vector<Key> const& keys) {
5951
std::vector<Value> kv;
6052
for (Key const& k : keys)
@@ -65,7 +57,8 @@ void associative_container_benchmarks(std::string container) {
6557
auto get_key = [](Value const& v) { return adapt_operations<Container>::key_from_value(v); };
6658

6759
auto bench = [&](std::string operation, auto f) {
68-
benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(32)->Arg(1024)->Arg(8192);
60+
// Note: Add zero to the range for empty containers.
61+
benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(0)->Arg(32)->Arg(1024)->Arg(8192);
6962
};
7063

7164
static constexpr bool is_multi_key_container =
@@ -180,7 +173,8 @@ void associative_container_benchmarks(std::string container) {
180173
// Insertion
181174
/////////////////////////
182175
bench("insert(value) (already present)", [=](auto& st) {
183-
const std::size_t size = st.range(0);
176+
// Make sure non-empty container for |to_insert| to be present and no segfault.
177+
const std::size_t size = st.range(0) ? st.range(0) : 1;
184178
std::vector<Value> in = make_value_types(generate_unique_keys(size));
185179
Value to_insert = in[in.size() / 2]; // pick any existing value
186180
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
@@ -333,7 +327,7 @@ void associative_container_benchmarks(std::string container) {
333327
// Erasure
334328
/////////////////////////
335329
bench("erase(key) (existent)", [=](auto& st) {
336-
const std::size_t size = st.range(0);
330+
const std::size_t size = st.range(0) ? st.range(0) : 1; // avoid empty container
337331
std::vector<Value> in = make_value_types(generate_unique_keys(size));
338332
Value element = in[in.size() / 2]; // pick any element
339333
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
@@ -377,7 +371,7 @@ void associative_container_benchmarks(std::string container) {
377371
});
378372

379373
bench("erase(iterator)", [=](auto& st) {
380-
const std::size_t size = st.range(0);
374+
const std::size_t size = st.range(0) ? st.range(0) : 1; // avoid empty container
381375
std::vector<Value> in = make_value_types(generate_unique_keys(size));
382376
Value element = in[in.size() / 2]; // pick any element
383377

@@ -456,7 +450,7 @@ void associative_container_benchmarks(std::string container) {
456450
Container c(in.begin(), in.end());
457451

458452
while (st.KeepRunningBatch(BatchSize)) {
459-
for (std::size_t i = 0; i != BatchSize; ++i) {
453+
for (std::size_t i = 0; i != keys.size(); ++i) { // possible empty keys when Arg(0)
460454
auto result = func(c, keys[i]);
461455
benchmark::DoNotOptimize(c);
462456
benchmark::DoNotOptimize(result);
@@ -488,37 +482,17 @@ void associative_container_benchmarks(std::string container) {
488482
};
489483
};
490484

491-
auto with_expensive_key_empty = [=](auto func) {
492-
return [=](auto& st) {
493-
const std::size_t size = st.range(0);
494-
std::vector<Key> keys = generate_expensive_keys(size);
495-
Container c;
496-
497-
while (st.KeepRunningBatch(BatchSize)) {
498-
for (std::size_t i = 0; i != BatchSize; ++i) {
499-
auto result = func(c, keys[i]);
500-
benchmark::DoNotOptimize(c);
501-
benchmark::DoNotOptimize(result);
502-
benchmark::ClobberMemory();
503-
}
504-
}
505-
};
506-
};
507-
508485
auto find = [](Container const& c, Key const& key) { return c.find(key); };
509486
bench("find(key) (existent)", with_existent_key(find));
510487
bench("find(key) (non-existent)", with_nonexistent_key(find));
511-
bench("find(key) (expensive-empty)", with_expensive_key_empty(find));
512488

513489
auto count = [](Container const& c, Key const& key) { return c.count(key); };
514490
bench("count(key) (existent)", with_existent_key(count));
515491
bench("count(key) (non-existent)", with_nonexistent_key(count));
516-
bench("count(key) (expensive-empty)", with_expensive_key_empty(count));
517492

518493
auto contains = [](Container const& c, Key const& key) { return c.contains(key); };
519494
bench("contains(key) (existent)", with_existent_key(contains));
520495
bench("contains(key) (non-existent)", with_nonexistent_key(contains));
521-
bench("contains(key) (expensive-empty)", with_expensive_key_empty(contains));
522496

523497
if constexpr (is_ordered_container) {
524498
auto lower_bound = [](Container const& c, Key const& key) { return c.lower_bound(key); };

0 commit comments

Comments
 (0)