mirror of
https://github.com/google/benchmark.git
synced 2025-02-04 08:10:17 +08:00
Update README.md
Switched to language specific markdown for code sections to provide syntax highlighting when rendered.
This commit is contained in:
parent
0a1593b06f
commit
465cb09eb6
196
README.md
196
README.md
@ -10,87 +10,97 @@ Example usage:
|
|||||||
Define a function that executes the code to be measured a
|
Define a function that executes the code to be measured a
|
||||||
specified number of times:
|
specified number of times:
|
||||||
|
|
||||||
static void BM_StringCreation(benchmark::State& state) {
|
```c++
|
||||||
while (state.KeepRunning())
|
static void BM_StringCreation(benchmark::State& state) {
|
||||||
std::string empty_string;
|
while (state.KeepRunning())
|
||||||
}
|
std::string empty_string;
|
||||||
// Register the function as a benchmark
|
}
|
||||||
BENCHMARK(BM_StringCreation);
|
// Register the function as a benchmark
|
||||||
|
BENCHMARK(BM_StringCreation);
|
||||||
|
|
||||||
// Define another benchmark
|
// Define another benchmark
|
||||||
static void BM_StringCopy(benchmark::State& state) {
|
static void BM_StringCopy(benchmark::State& state) {
|
||||||
std::string x = "hello";
|
std::string x = "hello";
|
||||||
while (state.KeepRunning())
|
while (state.KeepRunning())
|
||||||
std::string copy(x);
|
std::string copy(x);
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_StringCopy);
|
BENCHMARK(BM_StringCopy);
|
||||||
|
|
||||||
// Augment the main() program to invoke benchmarks if specified
|
// Augment the main() program to invoke benchmarks if specified
|
||||||
// via the --benchmarks command line flag. E.g.,
|
// via the --benchmarks command line flag. E.g.,
|
||||||
// my_unittest --benchmark_filter=all
|
// my_unittest --benchmark_filter=all
|
||||||
// my_unittest --benchmark_filter=BM_StringCreation
|
// my_unittest --benchmark_filter=BM_StringCreation
|
||||||
// my_unittest --benchmark_filter=String
|
// my_unittest --benchmark_filter=String
|
||||||
// my_unittest --benchmark_filter='Copy|Creation'
|
// my_unittest --benchmark_filter='Copy|Creation'
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
benchmark::Initialize(&argc, argv);
|
benchmark::Initialize(&argc, argv);
|
||||||
benchmark::RunSpecifiedBenchmarks();
|
benchmark::RunSpecifiedBenchmarks();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Sometimes a family of microbenchmarks can be implemented with
|
Sometimes a family of microbenchmarks can be implemented with
|
||||||
just one routine that takes an extra argument to specify which
|
just one routine that takes an extra argument to specify which
|
||||||
one of the family of benchmarks to run. For example, the following
|
one of the family of benchmarks to run. For example, the following
|
||||||
code defines a family of microbenchmarks for measuring the speed
|
code defines a family of microbenchmarks for measuring the speed
|
||||||
of memcpy() calls of different lengths:
|
of `memcpy()` calls of different lengths:
|
||||||
|
|
||||||
static void BM_memcpy(benchmark::State& state) {
|
```c++
|
||||||
char* src = new char[state.range_x()]; char* dst = new char[state.range_x()];
|
static void BM_memcpy(benchmark::State& state) {
|
||||||
memset(src, 'x', state.range_x());
|
char* src = new char[state.range_x()]; char* dst = new char[state.range_x()];
|
||||||
while (state.KeepRunning()) {
|
memset(src, 'x', state.range_x());
|
||||||
memcpy(dst, src, state.range_x());
|
while (state.KeepRunning()) {
|
||||||
benchmark::SetBenchmarkBytesProcessed(
|
memcpy(dst, src, state.range_x());
|
||||||
int64_t(state.iterations) * int64_t(state.range_x()));
|
benchmark::SetBenchmarkBytesProcessed(
|
||||||
delete[] src;
|
int64_t(state.iterations) * int64_t(state.range_x()));
|
||||||
delete[] dst;
|
delete[] src;
|
||||||
}
|
delete[] dst;
|
||||||
BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
|
}
|
||||||
|
BENCHMARK(BM_memcpy)->Arg(8)->Arg(64)->Arg(512)->Arg(1<<10)->Arg(8<<10);
|
||||||
|
```
|
||||||
|
|
||||||
The preceding code is quite repetitive, and can be replaced with the
|
The preceding code is quite repetitive, and can be replaced with the
|
||||||
following short-hand. The following invocation will pick a few
|
following short-hand. The following invocation will pick a few
|
||||||
appropriate arguments in the specified range and will generate a
|
appropriate arguments in the specified range and will generate a
|
||||||
microbenchmark for each such argument.
|
microbenchmark for each such argument.
|
||||||
|
|
||||||
BENCHMARK(BM_memcpy)->Range(8, 8<<10);
|
```c++
|
||||||
|
BENCHMARK(BM_memcpy)->Range(8, 8<<10);
|
||||||
|
```
|
||||||
|
|
||||||
You might have a microbenchmark that depends on two inputs. For
|
You might have a microbenchmark that depends on two inputs. For
|
||||||
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) {
|
```c++
|
||||||
while (state.KeepRunning()) {
|
static void BM_SetInsert(benchmark::State& state) {
|
||||||
state.PauseTiming();
|
while (state.KeepRunning()) {
|
||||||
std::set<int> data = ConstructRandomSet(state.range_x());
|
state.PauseTiming();
|
||||||
state.ResumeTiming();
|
std::set<int> data = ConstructRandomSet(state.range_x());
|
||||||
for (int j = 0; j < state.rangeY; ++j)
|
state.ResumeTiming();
|
||||||
data.insert(RandomNumber());
|
for (int j = 0; j < state.rangeY; ++j)
|
||||||
}
|
data.insert(RandomNumber());
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_SetInsert)
|
}
|
||||||
->ArgPair(1<<10, 1)
|
BENCHMARK(BM_SetInsert)
|
||||||
->ArgPair(1<<10, 8)
|
->ArgPair(1<<10, 1)
|
||||||
->ArgPair(1<<10, 64)
|
->ArgPair(1<<10, 8)
|
||||||
->ArgPair(1<<10, 512)
|
->ArgPair(1<<10, 64)
|
||||||
->ArgPair(8<<10, 1)
|
->ArgPair(1<<10, 512)
|
||||||
->ArgPair(8<<10, 8)
|
->ArgPair(8<<10, 1)
|
||||||
->ArgPair(8<<10, 64)
|
->ArgPair(8<<10, 8)
|
||||||
->ArgPair(8<<10, 512);
|
->ArgPair(8<<10, 64)
|
||||||
|
->ArgPair(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)->RangePair(1<<10, 8<<10, 1, 512);
|
```c++
|
||||||
|
BENCHMARK(BM_SetInsert)->RangePair(1<<10, 8<<10, 1, 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
|
||||||
@ -98,48 +108,54 @@ arbitrary set of arguments to run the microbenchmark on.
|
|||||||
The following example enumerates a dense range on one parameter,
|
The following example enumerates a dense range on one parameter,
|
||||||
and a sparse range on the second.
|
and a sparse range on the second.
|
||||||
|
|
||||||
static benchmark::internal::Benchmark* CustomArguments(
|
```c++
|
||||||
benchmark::internal::Benchmark* b) {
|
static benchmark::internal::Benchmark* CustomArguments(
|
||||||
for (int i = 0; i <= 10; ++i)
|
benchmark::internal::Benchmark* b) {
|
||||||
for (int j = 32; j <= 1024*1024; j *= 8)
|
for (int i = 0; i <= 10; ++i)
|
||||||
b = b->ArgPair(i, j);
|
for (int j = 32; j <= 1024*1024; j *= 8)
|
||||||
return b;
|
b = b->ArgPair(i, j);
|
||||||
}
|
return b;
|
||||||
BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
|
}
|
||||||
|
BENCHMARK(BM_SetInsert)->Apply(CustomArguments);
|
||||||
|
```
|
||||||
|
|
||||||
Templated microbenchmarks work the same way:
|
Templated microbenchmarks work the same way:
|
||||||
Produce then consume 'size' messages 'iters' times
|
Produce then consume 'size' messages 'iters' times
|
||||||
Measures throughput in the absence of multiprogramming.
|
Measures throughput in the absence of multiprogramming.
|
||||||
|
|
||||||
template <class Q> int BM_Sequential(benchmark::State& state) {
|
```c++
|
||||||
Q q;
|
template <class Q> int BM_Sequential(benchmark::State& state) {
|
||||||
typename Q::value_type v;
|
Q q;
|
||||||
while (state.KeepRunning()) {
|
typename Q::value_type v;
|
||||||
for (int i = state.range_x(); i--; )
|
while (state.KeepRunning()) {
|
||||||
q.push(v);
|
for (int i = state.range_x(); i--; )
|
||||||
for (int e = state.range_x(); e--; )
|
q.push(v);
|
||||||
q.Wait(&v);
|
for (int e = state.range_x(); e--; )
|
||||||
}
|
q.Wait(&v);
|
||||||
// actually messages, not bytes:
|
}
|
||||||
state.SetBytesProcessed(
|
// actually messages, not bytes:
|
||||||
static_cast<int64_t>(state.iterations())*state.range_x());
|
state.SetBytesProcessed(
|
||||||
}
|
static_cast<int64_t>(state.iterations())*state.range_x());
|
||||||
BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
|
}
|
||||||
|
BENCHMARK_TEMPLATE(BM_Sequential, WaitQueue<int>)->Range(1<<0, 1<<10);
|
||||||
|
```
|
||||||
|
|
||||||
In a multithreaded test, it is guaranteed that none of the threads will start
|
In a multithreaded test, it is guaranteed that none of the threads will start
|
||||||
until all have called KeepRunning, and all will have finished before KeepRunning
|
until all have called KeepRunning, and all will have finished before KeepRunning
|
||||||
returns false. As such, any global setup or teardown you want to do can be
|
returns false. As such, any global setup or teardown you want to do can be
|
||||||
wrapped in a check against the thread index:
|
wrapped in a check against the thread index:
|
||||||
|
|
||||||
static void BM_MultiThreaded(benchmark::State& state) {
|
```c++
|
||||||
if (state.thread_index == 0) {
|
static void BM_MultiThreaded(benchmark::State& state) {
|
||||||
// Setup code here.
|
if (state.thread_index == 0) {
|
||||||
}
|
// Setup code here.
|
||||||
while (state.KeepRunning()) {
|
}
|
||||||
// Run the test as normal.
|
while (state.KeepRunning()) {
|
||||||
}
|
// Run the test as normal.
|
||||||
if (state.thread_index == 0) {
|
}
|
||||||
// Teardown code here.
|
if (state.thread_index == 0) {
|
||||||
}
|
// Teardown code here.
|
||||||
}
|
}
|
||||||
BENCHMARK(BM_MultiThreaded)->Threads(2);
|
}
|
||||||
|
BENCHMARK(BM_MultiThreaded)->Threads(2);
|
||||||
|
```
|
||||||
|
Loading…
Reference in New Issue
Block a user