As far as I can remember, the function is called multiple times, since benchmark
dynamically decides how many times your benchmark needs to be run in order to get reliable results. If you don't want to use fixtures, there are multiple workarounds. You can use a global or static class member bool
to check if the setup function was already called (don't forget to set it after the setup routine has run). Another possibility is to use a Singleton that calls the setup method in its ctor:
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) {
// ...
}
}
However, fixtures are quite simple to use and are made for such use-cases.
Define a fixture class which inherits from 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
}
};
Then use the BENCHMARK_F
macro to use your fixture in the test.
BENCHMARK_F(MyFixture, TestcaseName)(benchmark::State& state)
{
std::cout << "Benchmark function called more than once" << std::endl;
for (auto _ : state)
{
//run your benchmark
}
}
However, if you use the fixture in multiple benchmarks, the ctor will be called multiple times. If you really need a certain setup function to be called only once during the whole benchmark, you can use a Singleton or a static bool
to work around this as described earlier. Maybe benchmark
also has a built-in solution for that, but I don't know it.
Alternative to Singleton
If you don't like the singleton class, you can also use a global function like this:
void Setup()
{
static bool callSetup = true;
if (callSetup)
{
// Call your setup function
}
callSetup = false;
}
Greetings