Насколько я помню, функция вызывается несколько раз, поскольку benchmark
динамически решает, сколько раз необходимо выполнить тест для получения надежных результатов. Если вы не хотите использовать приборы, есть несколько обходных путей. Вы можете использовать глобальный или статический член класса bool
, чтобы проверить, была ли уже вызвана функция установки (не забудьте установить ее после запуска процедуры установки). Другая возможность - использовать Singleton, который вызывает метод установки в своем 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) {
// ...
}
}
Однако приборы довольно просты в использовании и созданы для таких случаев использования.
Определите класс прибора, который наследуется от 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
}
};
Затем используйте макрос 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
}
}
Однако, если вы используете прибор в нескольких тестах, ctor будет вызываться несколько раз. Если вам действительно нужно, чтобы определенная функция настройки вызывалась только один раз в течение всего теста, вы можете использовать Singleton или static bool
, чтобы обойти это, как описано ранее. Может быть, benchmark
также имеет встроенное решение для этого, но я его не знаю.
Альтернатива Singleton
Если вы неКак и в случае синглтон-класса, вы также можете использовать глобальную функцию, подобную этой:
void Setup()
{
static bool callSetup = true;
if (callSetup)
{
// Call your setup function
}
callSetup = false;
}
Greetings