如何使用Google基准测试对自定义界面进行基准测试

时间:2020-05-31 11:57:50

标签: c++ google-benchmark

由于除了github自述文件之外,我找不到真正好的资源或文档,因此我将在此处询问社区。

假设我有一个名为Base的接口,并且有多个派生类型。
我想对传递给Foo的相同函数和相同参数对所有派生类型的虚函数Foo进行基准测试。
对于每种派生类型,我想在一个基准中多次调用Foo,并从std::vector<std::size_t>传递不同的参数。

我的某些派生类型的构造函数也需要额外的参数,我应该如何处理呢?

我认为最简单的方法是使用模板化基准测试并传递给:

const std::vector<std::size_t> v {1, 2, 4, 8, 16};
BENCHMARK_TEMPLATE(func, Derived1, v);
BENCHMARK_TEMPLATE(func, Derived2, v);
BENCHMARK_TEMPLATE(func, Derived3, v);
...

我不认为这是正确的方法,因为对于具有不同构造函数签名的每个派生类型,我将需要具有与上一个几乎相同的基准函数。

基准测试的正确方法是什么?

**更新*: 我解决此问题的方法如下:

std::unique_ptr<Base> GetObj(const std::size_t index)
{
    switch(index)
    {
    case 0:
        return std::make_unique<Derived1>(...);
    case 1:
        return std::make_unique<Derived2>(...);
    ...
    }
}

void func(benchmark::State& state)
{
    auto r = state.range();
    auto object = GetObj(r);
    for (auto _ : state)
    {
        ...
    }
}
BENCHMARK(func)->DenseRange(0,5);

但是我不喜欢基准测试的名称是func/0-5模式,我希望它是func/Derived1func/Derived2等..有什么想法要实现吗?

1 个答案:

答案 0 :(得分:1)

您的方法几乎是正确的。如果要避免使用多个基准测试功能,请将基准测试的核心移至单独的函数,然后从每个类型的函数中调用它。像这样:

static void Benchmark(Base* b, benchmark::State& st) {
  for (auto _ : state) {
    b->DoTheThing()
  }
}

void BM_Foo(benchmark::State& st) {
  Foo f;
  Benchmark(&f, st);
}

BENCHMARK(BM_Foo);

如果您想变得更复杂,可以使用RegisterBenchmark函数来更灵活地注册内容。像这样:

auto BM_base = [](benchmark::State& st, auto inputs, Base* b) { /* ... */ };

int main(int argc, char**argv) {
  const std::vector<std::size_t> v = {1, 2, 4, 8, 16};
  benchmark::RegisterBenchmark("foo", BM_base, v, new Foo());
  benchmark::Initialize(&argc, argv);
  return benchmark::RunSpecifiedBenchmarks();
}

顺便说一句,在注册基准测试时应将v设置为Arg吗?