Commit fa341e51 by Leo Koppel Committed by Dominic Hamon

Improve BM_SetInsert example (#465)

* Fix BM_SetInsert example Move declaration of `std::set<int> data` outside the timing loop, so that the destructor is not timed. * Speed up BM_SetInsert test Since the time taken to ConstructRandomSet() is so large compared to the time to insert one element, but only the latter is used to determine number of iterations, this benchmark now takes an extremely long time to run in benchmark_test. Speed it up two ways: - Increase the Ranges() parameters - Cache ConstructRandomSet() result (it's not random anyway), and do only O(N) copy every iteration * Fix same issue in BM_MapLookup test * Make BM_SetInsert test consistent with README - Use the same Ranges everywhere, but increase the 2nd range - Change order of Args() calls in README to more closely match the result of Ranges - Don't cache ConstructRandomSet, since it doesn't make sense in README - Get a smaller optimization inside it, by givint a hint to insert()
parent 491360b8
...@@ -84,22 +84,23 @@ insertion. ...@@ -84,22 +84,23 @@ insertion.
```c++ ```c++
static void BM_SetInsert(benchmark::State& state) { static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) { for (auto _ : state) {
state.PauseTiming(); state.PauseTiming();
std::set<int> data = ConstructRandomSet(state.range(0)); data = ConstructRandomSet(state.range(0));
state.ResumeTiming(); state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j) for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber()); data.insert(RandomNumber());
} }
} }
BENCHMARK(BM_SetInsert) BENCHMARK(BM_SetInsert)
->Args({1<<10, 1}) ->Args({1<<10, 128})
->Args({1<<10, 8}) ->Args({2<<10, 128})
->Args({1<<10, 64}) ->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512}) ->Args({1<<10, 512})
->Args({8<<10, 1}) ->Args({2<<10, 512})
->Args({8<<10, 8}) ->Args({4<<10, 512})
->Args({8<<10, 64})
->Args({8<<10, 512}); ->Args({8<<10, 512});
``` ```
...@@ -109,7 +110,7 @@ product of the two specified ranges and will generate a benchmark for each such ...@@ -109,7 +110,7 @@ product of the two specified ranges and will generate a benchmark for each such
pair. pair.
```c++ ```c++
BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
``` ```
For more complex patterns of inputs, passing a custom function to `Apply` allows For more complex patterns of inputs, passing a custom function to `Apply` allows
......
...@@ -72,29 +72,30 @@ BENCHMARK(BM_memcpy)->Range(8, 8<<10); ...@@ -72,29 +72,30 @@ BENCHMARK(BM_memcpy)->Range(8, 8<<10);
// example, the following code defines a family of microbenchmarks for // example, the following code defines a family of microbenchmarks for
// measuring the speed of set insertion. // measuring the speed of set insertion.
static void BM_SetInsert(benchmark::State& state) { static void BM_SetInsert(benchmark::State& state) {
set<int> data;
for (auto _ : state) { for (auto _ : state) {
state.PauseTiming(); state.PauseTiming();
set<int> data = ConstructRandomSet(state.range(0)); data = ConstructRandomSet(state.range(0));
state.ResumeTiming(); state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j) for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber()); data.insert(RandomNumber());
} }
} }
BENCHMARK(BM_SetInsert) BENCHMARK(BM_SetInsert)
->Args({1<<10, 1}) ->Args({1<<10, 128})
->Args({1<<10, 8}) ->Args({2<<10, 128})
->Args({1<<10, 64}) ->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512}) ->Args({1<<10, 512})
->Args({8<<10, 1}) ->Args({2<<10, 512})
->Args({8<<10, 8}) ->Args({4<<10, 512})
->Args({8<<10, 64})
->Args({8<<10, 512}); ->Args({8<<10, 512});
// The preceding code is quite repetitive, and can be replaced with // The preceding code is quite repetitive, and can be replaced with
// the following short-hand. The following macro will pick a few // the following short-hand. The following macro will pick a few
// appropriate arguments in the product of the two specified ranges // appropriate arguments in the product of the two specified ranges
// and will generate a microbenchmark for each such pair. // and will generate a microbenchmark for each such pair.
BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {1, 512}}); BENCHMARK(BM_SetInsert)->Ranges({{1<<10, 8<<10}, {128, 512}});
// For more complex patterns of inputs, passing a custom function // For more complex patterns of inputs, passing a custom function
// to Apply allows programmatic specification of an // to Apply allows programmatic specification of an
......
...@@ -42,7 +42,7 @@ double CalculatePi(int depth) { ...@@ -42,7 +42,7 @@ double CalculatePi(int depth) {
std::set<int> ConstructRandomSet(int size) { std::set<int> ConstructRandomSet(int size) {
std::set<int> s; std::set<int> s;
for (int i = 0; i < size; ++i) s.insert(i); for (int i = 0; i < size; ++i) s.insert(s.end(), i);
return s; return s;
} }
...@@ -82,16 +82,20 @@ BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32); ...@@ -82,16 +82,20 @@ BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32);
BENCHMARK(BM_CalculatePi)->ThreadPerCpu(); BENCHMARK(BM_CalculatePi)->ThreadPerCpu();
static void BM_SetInsert(benchmark::State& state) { static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) { for (auto _ : state) {
state.PauseTiming(); state.PauseTiming();
std::set<int> data = ConstructRandomSet(state.range(0)); data = ConstructRandomSet(state.range(0));
state.ResumeTiming(); state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j) data.insert(rand()); for (int j = 0; j < state.range(1); ++j) data.insert(rand());
} }
state.SetItemsProcessed(state.iterations() * state.range(1)); state.SetItemsProcessed(state.iterations() * state.range(1));
state.SetBytesProcessed(state.iterations() * state.range(1) * sizeof(int)); state.SetBytesProcessed(state.iterations() * state.range(1) * sizeof(int));
} }
BENCHMARK(BM_SetInsert)->Ranges({{1 << 10, 8 << 10}, {1, 10}});
// Test many inserts at once to reduce the total iterations needed. Otherwise, the slower,
// non-timed part of each iteration will make the benchmark take forever.
BENCHMARK(BM_SetInsert)->Ranges({{1 << 10, 8 << 10}, {128, 512}});
template <typename Container, template <typename Container,
typename ValueType = typename Container::value_type> typename ValueType = typename Container::value_type>
......
...@@ -18,9 +18,10 @@ std::map<int, int> ConstructRandomMap(int size) { ...@@ -18,9 +18,10 @@ std::map<int, int> ConstructRandomMap(int size) {
// Basic version. // Basic version.
static void BM_MapLookup(benchmark::State& state) { static void BM_MapLookup(benchmark::State& state) {
const int size = state.range(0); const int size = state.range(0);
std::map<int, int> m;
for (auto _ : state) { for (auto _ : state) {
state.PauseTiming(); state.PauseTiming();
std::map<int, int> m = ConstructRandomMap(size); m = ConstructRandomMap(size);
state.ResumeTiming(); state.ResumeTiming();
for (int i = 0; i < size; ++i) { for (int i = 0; i < size; ++i) {
benchmark::DoNotOptimize(m.find(rand() % size)); benchmark::DoNotOptimize(m.find(rand() % size));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment