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()
This commit is contained in:
Leo Koppel 2017-10-31 14:00:39 -04:00 committed by Dominic Hamon
parent 491360b833
commit fa341e51cb
4 changed files with 27 additions and 20 deletions

View File

@ -84,22 +84,23 @@ insertion.
```c++
static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) {
state.PauseTiming();
std::set<int> data = ConstructRandomSet(state.range(0));
data = ConstructRandomSet(state.range(0));
state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber());
}
}
BENCHMARK(BM_SetInsert)
->Args({1<<10, 1})
->Args({1<<10, 8})
->Args({1<<10, 64})
->Args({1<<10, 128})
->Args({2<<10, 128})
->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512})
->Args({8<<10, 1})
->Args({8<<10, 8})
->Args({8<<10, 64})
->Args({2<<10, 512})
->Args({4<<10, 512})
->Args({8<<10, 512});
```
@ -109,7 +110,7 @@ product of the two specified ranges and will generate a benchmark for each such
pair.
```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

View File

@ -72,29 +72,30 @@ BENCHMARK(BM_memcpy)->Range(8, 8<<10);
// example, the following code defines a family of microbenchmarks for
// measuring the speed of set insertion.
static void BM_SetInsert(benchmark::State& state) {
set<int> data;
for (auto _ : state) {
state.PauseTiming();
set<int> data = ConstructRandomSet(state.range(0));
data = ConstructRandomSet(state.range(0));
state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j)
data.insert(RandomNumber());
}
}
BENCHMARK(BM_SetInsert)
->Args({1<<10, 1})
->Args({1<<10, 8})
->Args({1<<10, 64})
->Args({1<<10, 128})
->Args({2<<10, 128})
->Args({4<<10, 128})
->Args({8<<10, 128})
->Args({1<<10, 512})
->Args({8<<10, 1})
->Args({8<<10, 8})
->Args({8<<10, 64})
->Args({2<<10, 512})
->Args({4<<10, 512})
->Args({8<<10, 512});
// The preceding code is quite repetitive, and can be replaced with
// the following short-hand. The following macro will pick a few
// appropriate arguments in the product of the two specified ranges
// 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
// to Apply allows programmatic specification of an

View File

@ -42,7 +42,7 @@ double CalculatePi(int depth) {
std::set<int> ConstructRandomSet(int size) {
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;
}
@ -82,16 +82,20 @@ BENCHMARK(BM_CalculatePi)->ThreadRange(1, 32);
BENCHMARK(BM_CalculatePi)->ThreadPerCpu();
static void BM_SetInsert(benchmark::State& state) {
std::set<int> data;
for (auto _ : state) {
state.PauseTiming();
std::set<int> data = ConstructRandomSet(state.range(0));
data = ConstructRandomSet(state.range(0));
state.ResumeTiming();
for (int j = 0; j < state.range(1); ++j) data.insert(rand());
}
state.SetItemsProcessed(state.iterations() * state.range(1));
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,
typename ValueType = typename Container::value_type>

View File

@ -18,9 +18,10 @@ std::map<int, int> ConstructRandomMap(int size) {
// Basic version.
static void BM_MapLookup(benchmark::State& state) {
const int size = state.range(0);
std::map<int, int> m;
for (auto _ : state) {
state.PauseTiming();
std::map<int, int> m = ConstructRandomMap(size);
m = ConstructRandomMap(size);
state.ResumeTiming();
for (int i = 0; i < size; ++i) {
benchmark::DoNotOptimize(m.find(rand() % size));