mirror of https://github.com/google/benchmark.git
Add `BENCHMARK_TEMPLATE[12]_CAPTURE`, fusion of `BENCHMARK_CAPTURE` and `BENCHMARK_TEMPLATE` (#1747)
Test coverage isn't great, but not worse than the existing one. You'd think `BENCHMARK_CAPTURE` would suffice, but you can't pass `func<targs>` to it (due to the `<` and `>`), and when passing `(func<targs>)` we get issues with brackets. So i'm not sure if we can fully avoid this helper. That being said, if there is only a single template argument, `BENCHMARK_CAPTURE()` works fine if we avoid using function name.
This commit is contained in:
parent
30a37e1b0b
commit
e990563876
|
@ -28,6 +28,8 @@
|
||||||
|
|
||||||
[Templated Benchmarks](#templated-benchmarks)
|
[Templated Benchmarks](#templated-benchmarks)
|
||||||
|
|
||||||
|
[Templated Benchmarks that take arguments](#templated-benchmarks-with-arguments)
|
||||||
|
|
||||||
[Fixtures](#fixtures)
|
[Fixtures](#fixtures)
|
||||||
|
|
||||||
[Custom Counters](#custom-counters)
|
[Custom Counters](#custom-counters)
|
||||||
|
@ -574,6 +576,30 @@ Three macros are provided for adding benchmark templates.
|
||||||
#define BENCHMARK_TEMPLATE2(func, arg1, arg2)
|
#define BENCHMARK_TEMPLATE2(func, arg1, arg2)
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<a name="templated-benchmarks-with-arguments" />
|
||||||
|
|
||||||
|
## Templated Benchmarks that take arguments
|
||||||
|
|
||||||
|
Sometimes there is a need to template benchmarks, and provide arguments to them.
|
||||||
|
|
||||||
|
```c++
|
||||||
|
template <class Q> void BM_Sequential_With_Step(benchmark::State& state, int step) {
|
||||||
|
Q q;
|
||||||
|
typename Q::value_type v;
|
||||||
|
for (auto _ : state) {
|
||||||
|
for (int i = state.range(0); i-=step; )
|
||||||
|
q.push(v);
|
||||||
|
for (int e = state.range(0); e-=step; )
|
||||||
|
q.Wait(&v);
|
||||||
|
}
|
||||||
|
// actually messages, not bytes:
|
||||||
|
state.SetBytesProcessed(
|
||||||
|
static_cast<int64_t>(state.iterations())*state.range(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
BENCHMARK_TEMPLATE1_CAPTURE(BM_Sequential, WaitQueue<int>, Step1, 1)->Range(1<<0, 1<<10);
|
||||||
|
```
|
||||||
|
|
||||||
<a name="fixtures" />
|
<a name="fixtures" />
|
||||||
|
|
||||||
## Fixtures
|
## Fixtures
|
||||||
|
|
|
@ -1523,7 +1523,7 @@ class Fixture : public internal::Benchmark {
|
||||||
// /* Registers a benchmark named "BM_takes_args/int_string_test` */
|
// /* Registers a benchmark named "BM_takes_args/int_string_test` */
|
||||||
// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
|
// BENCHMARK_CAPTURE(BM_takes_args, int_string_test, 42, std::string("abc"));
|
||||||
#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
|
#define BENCHMARK_CAPTURE(func, test_case_name, ...) \
|
||||||
BENCHMARK_PRIVATE_DECLARE(func) = \
|
BENCHMARK_PRIVATE_DECLARE(_benchmark_) = \
|
||||||
(::benchmark::internal::RegisterBenchmarkInternal( \
|
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||||
new ::benchmark::internal::FunctionBenchmark( \
|
new ::benchmark::internal::FunctionBenchmark( \
|
||||||
#func "/" #test_case_name, \
|
#func "/" #test_case_name, \
|
||||||
|
@ -1560,6 +1560,31 @@ class Fixture : public internal::Benchmark {
|
||||||
#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
|
#define BENCHMARK_TEMPLATE(n, a) BENCHMARK_TEMPLATE1(n, a)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef BENCHMARK_HAS_CXX11
|
||||||
|
// This will register a benchmark for a templatized function,
|
||||||
|
// with the additional arguments specified by `...`.
|
||||||
|
//
|
||||||
|
// For example:
|
||||||
|
//
|
||||||
|
// template <typename T, class ...ExtraArgs>`
|
||||||
|
// void BM_takes_args(benchmark::State& state, ExtraArgs&&... extra_args) {
|
||||||
|
// [...]
|
||||||
|
//}
|
||||||
|
// /* Registers a benchmark named "BM_takes_args<void>/int_string_test` */
|
||||||
|
// BENCHMARK_TEMPLATE1_CAPTURE(BM_takes_args, void, int_string_test, 42,
|
||||||
|
// std::string("abc"));
|
||||||
|
#define BENCHMARK_TEMPLATE1_CAPTURE(func, a, test_case_name, ...) \
|
||||||
|
BENCHMARK_CAPTURE(func<a>, test_case_name, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define BENCHMARK_TEMPLATE2_CAPTURE(func, a, b, test_case_name, ...) \
|
||||||
|
BENCHMARK_PRIVATE_DECLARE(func) = \
|
||||||
|
(::benchmark::internal::RegisterBenchmarkInternal( \
|
||||||
|
new ::benchmark::internal::FunctionBenchmark( \
|
||||||
|
#func "<" #a "," #b ">" \
|
||||||
|
"/" #test_case_name, \
|
||||||
|
[](::benchmark::State& st) { func<a, b>(st, __VA_ARGS__); })))
|
||||||
|
#endif // BENCHMARK_HAS_CXX11
|
||||||
|
|
||||||
#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
|
#define BENCHMARK_PRIVATE_DECLARE_F(BaseClass, Method) \
|
||||||
class BaseClass##_##Method##_Benchmark : public BaseClass { \
|
class BaseClass##_##Method##_Benchmark : public BaseClass { \
|
||||||
public: \
|
public: \
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <type_traits>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
@ -226,6 +227,31 @@ void BM_non_template_args(benchmark::State& state, int, double) {
|
||||||
}
|
}
|
||||||
BENCHMARK_CAPTURE(BM_non_template_args, basic_test, 0, 0);
|
BENCHMARK_CAPTURE(BM_non_template_args, basic_test, 0, 0);
|
||||||
|
|
||||||
|
template <class T, class U, class... ExtraArgs>
|
||||||
|
void BM_template2_capture(benchmark::State& state, ExtraArgs&&... extra_args) {
|
||||||
|
static_assert(std::is_same<T, void>::value, "");
|
||||||
|
static_assert(std::is_same<U, char*>::value, "");
|
||||||
|
static_assert(std::is_same<ExtraArgs..., unsigned int>::value, "");
|
||||||
|
unsigned int dummy[sizeof...(ExtraArgs)] = {extra_args...};
|
||||||
|
assert(dummy[0] == 42);
|
||||||
|
for (auto _ : state) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BENCHMARK_TEMPLATE2_CAPTURE(BM_template2_capture, void, char*, foo, 42U);
|
||||||
|
BENCHMARK_CAPTURE((BM_template2_capture<void, char*>), foo, 42U);
|
||||||
|
|
||||||
|
template <class T, class... ExtraArgs>
|
||||||
|
void BM_template1_capture(benchmark::State& state, ExtraArgs&&... extra_args) {
|
||||||
|
static_assert(std::is_same<T, void>::value, "");
|
||||||
|
static_assert(std::is_same<ExtraArgs..., unsigned long>::value, "");
|
||||||
|
unsigned long dummy[sizeof...(ExtraArgs)] = {extra_args...};
|
||||||
|
assert(dummy[0] == 24);
|
||||||
|
for (auto _ : state) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
BENCHMARK_TEMPLATE1_CAPTURE(BM_template1_capture, void, foo, 24UL);
|
||||||
|
BENCHMARK_CAPTURE(BM_template1_capture<void>, foo, 24UL);
|
||||||
|
|
||||||
#endif // BENCHMARK_HAS_CXX11
|
#endif // BENCHMARK_HAS_CXX11
|
||||||
|
|
||||||
static void BM_DenseThreadRanges(benchmark::State& st) {
|
static void BM_DenseThreadRanges(benchmark::State& st) {
|
||||||
|
|
Loading…
Reference in New Issue