Google Benchmark自定义安装和拆卸方法

Kis*_*mar 7 c++ benchmarking microbenchmark google-benchmark

我正在使用基准库来对一些代码进行基准测试。我想在一次调用实际基准代码之前调用一个设置方法,而不是每次都重复调用,以便进行多个基准方法调用。例如:

static void BM_SomeFunction(benchmark::State& state) {
  // Perform setup here
  for (auto _ : state) {
    // This code gets timed
  }
}
Run Code Online (Sandbox Code Playgroud)

正如我们所看到的,对于我指定的范围,设置代码将在这里被多次调用。我确实查看了夹具测试。但我的问题是可以不使用夹具测试来完成吗?如果是的话我们该怎么做呢?

wyc*_*ter 9

据我记得,该函数被多次调用,因为benchmark动态决定基准测试需要运行多少次才能获得可靠的结果。如果您不想使用固定装置,有多种解决方法。您可以使用全局或静态类成员bool来检查设置函数是否已被调用(不要忘记在设置例程运行后设置它)。另一种可能性是使用在其构造函数中调用 setup 方法的 Singleton:

class Setup
{
    Setup()
    {
        // call your setup function
        std::cout << "singleton ctor called only once in the whole program" << std::endl;
    }

public:
    static void PerformSetup()
    {
        static Setup setup;
    }
};

static void BM_SomeFunction(benchmark::State& state) {
  Setup::PerformSetup()
  for (auto _ : state) {
    // ...
  }
}
Run Code Online (Sandbox Code Playgroud)

然而,固定装置使用起来非常简单,并且是为此类用例而设计的。

定义一个继承自的夹具类benchmark::Fixture

class MyFixture : public benchmark::Fixture
{
public:
    // add members as needed

    MyFixture()
    {
        std::cout << "Ctor only called once per fixture testcase hat uses it" << std::endl;
        // call whatever setup functions you need in the fixtures ctor 
    }
};
Run Code Online (Sandbox Code Playgroud)

然后使用BENCHMARK_F宏在测试中使用您的夹具。

BENCHMARK_F(MyFixture, TestcaseName)(benchmark::State& state)
{
    std::cout << "Benchmark function called more than once" << std::endl;
    for (auto _ : state)
    {
        //run your benchmark
    }
}
Run Code Online (Sandbox Code Playgroud)

但是,如果您在多个基准测试中使用该夹具,则该 ctor 将被多次调用。如果您确实需要在整个基准测试期间仅调用某个设置函数一次,则可以使用 Singleton 或 astatic bool来解决此问题,如前所述。也许benchmark也有一个内置的解决方案,但我不知道。


单例的替代方案

如果你不喜欢单例类,你也可以使用像这样的全局函数:

void Setup()
{
    static bool callSetup = true;
    if (callSetup)
    {
        // Call your setup function
    }
    callSetup = false;
}
Run Code Online (Sandbox Code Playgroud)

问候