Skip to content

Commit 9f109f8

Browse files
committed
Some tweaks to reduce variance
1 parent a4546d8 commit 9f109f8

File tree

4 files changed

+18
-17
lines changed

4 files changed

+18
-17
lines changed

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

Lines changed: 18 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <iterator>
1414
#include <random>
1515
#include <string>
16+
#include <type_traits>
17+
#include <utility>
1618
#include <vector>
1719

1820
#include "benchmark/benchmark.h"
@@ -58,6 +60,12 @@ void associative_container_benchmarks(std::string container) {
5860
benchmark::RegisterBenchmark(container + "::" + operation, f)->Arg(32)->Arg(1024)->Arg(8192);
5961
};
6062

63+
static constexpr bool is_multi_key_container =
64+
!std::is_same_v<typename adapt_operations<Container>::InsertionResult,
65+
std::pair<typename Container::iterator, bool>>;
66+
67+
static constexpr bool is_ordered_container = requires(Container c, Key k) { c.lower_bound(k); };
68+
6169
// These benchmarks are structured to perform the operation being benchmarked
6270
// a small number of times at each iteration, in order to offset the cost of
6371
// PauseTiming() and ResumeTiming().
@@ -168,26 +176,23 @@ void associative_container_benchmarks(std::string container) {
168176
std::vector<Value> in = make_value_types(generate_unique_keys(size));
169177
Value to_insert = in[in.size() / 2]; // pick any existing value
170178
std::vector<Container> c(BatchSize, Container(in.begin(), in.end()));
179+
typename Container::iterator inserted[BatchSize];
171180

172181
while (st.KeepRunningBatch(BatchSize)) {
173182
for (std::size_t i = 0; i != BatchSize; ++i) {
174-
auto result = c[i].insert(to_insert);
175-
benchmark::DoNotOptimize(result);
183+
inserted[i] = adapt_operations<Container>::get_iterator(c[i].insert(to_insert));
184+
benchmark::DoNotOptimize(inserted[i]);
176185
benchmark::DoNotOptimize(c[i]);
177186
benchmark::ClobberMemory();
178187
}
179188

180-
st.PauseTiming();
181-
// Unique-key containers will not insert above, but multi-key containers will insert
182-
// the key a second time. Restore the invariant that there's a single copy of each
183-
// key in the container.
184-
for (std::size_t i = 0; i != BatchSize; ++i) {
185-
auto const& key = get_key(to_insert);
186-
if (c[i].count(key) > 1) {
187-
c[i].erase(key);
189+
if constexpr (is_multi_key_container) {
190+
st.PauseTiming();
191+
for (std::size_t i = 0; i != BatchSize; ++i) {
192+
c[i].erase(inserted[i]);
188193
}
194+
st.ResumeTiming();
189195
}
190-
st.ResumeTiming();
191196
}
192197
});
193198

@@ -216,7 +221,7 @@ void associative_container_benchmarks(std::string container) {
216221

217222
// The insert(hint, ...) methods are only relevant for ordered containers, and we lack
218223
// a good way to compute a hint for unordered ones.
219-
if constexpr (requires(Container c, Key k) { c.lower_bound(k); }) {
224+
if constexpr (is_ordered_container) {
220225
bench("insert(hint, value) (good hint)", [=](auto& st) {
221226
const std::size_t size = st.range(0);
222227
std::vector<Value> in = make_value_types(generate_unique_keys(size + 1));
@@ -499,8 +504,7 @@ void associative_container_benchmarks(std::string container) {
499504
return c.contains(get_key(element));
500505
}));
501506

502-
// Only for ordered containers
503-
if constexpr (requires(Container c, Key k) { c.lower_bound(k); }) {
507+
if constexpr (is_ordered_container) {
504508
bench("lower_bound(key) (existent)", bench_with_existent_key([=](Container const& c, Value const& element) {
505509
return c.lower_bound(get_key(element));
506510
}));

libcxx/test/benchmarks/containers/associative/flat_map.bench.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ struct support::adapt_operations<std::flat_map<K, V>> {
2929

3030
int main(int argc, char** argv) {
3131
support::associative_container_benchmarks<std::flat_map<int, int>>("std::flat_map<int, int>");
32-
support::associative_container_benchmarks<std::flat_map<std::string, int>>("std::flat_map<std::string, int>");
3332

3433
benchmark::Initialize(&argc, argv);
3534
benchmark::RunSpecifiedBenchmarks();

libcxx/test/benchmarks/containers/associative/map.bench.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ struct support::adapt_operations<std::map<K, V>> {
2929

3030
int main(int argc, char** argv) {
3131
support::associative_container_benchmarks<std::map<int, int>>("std::map<int, int>");
32-
support::associative_container_benchmarks<std::map<std::string, int>>("std::map<std::string, int>");
3332

3433
benchmark::Initialize(&argc, argv);
3534
benchmark::RunSpecifiedBenchmarks();

libcxx/test/benchmarks/containers/associative/multimap.bench.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@ struct support::adapt_operations<std::multimap<K, V>> {
2828

2929
int main(int argc, char** argv) {
3030
support::associative_container_benchmarks<std::multimap<int, int>>("std::multimap<int, int>");
31-
support::associative_container_benchmarks<std::multimap<std::string, int>>("std::multimap<std::string, int>");
3231

3332
benchmark::Initialize(&argc, argv);
3433
benchmark::RunSpecifiedBenchmarks();

0 commit comments

Comments
 (0)