2

加载大文件后,我想使用谷歌基准库运行多个基准测试。为此,我使用以下代码。该函数read_collection()加载文件的内容,基准Build处理来自coll.

#define COLLECTION 'w'

class BuildFixture : public ::benchmark::Fixture {
 public:
     std::unique_ptr<Collection> coll;

     BuildFixture() {
        cout << "Constructor\n";
        coll = std::make_unique<Collection>(Collection(COLLECTION));
        coll->read_collection();
     }

     ~BuildFixture() {
         cout << "Destroy collection\n";
         coll.reset();
     }
};

BENCHMARK_DEFINE_F(BuildFixture, Build1)(benchmark::State& state) {
    nrows = static_cast<size_t>(state.range(0));
    for (auto _ : state) {
       // Do something with coll and nrows
    }
}

BENCHMARK_DEFINE_F(BuildFixture, Build2)(benchmark::State& state) {
    nrows = static_cast<size_t>(state.range(0));
    for (auto _ : state) {
       // Something else with coll and nrows
    }
}



BENCHMARK_REGISTER_F(BuildFixture, Build1)->Arg(10);
BENCHMARK_REGISTER_F(BuildFixture, Build2)->Arg(20);

BENCHMARK_MAIN();

当我运行这段代码时,每个带有参数 10 和 20 的基准测试都会执行构造函数(总共两次),运行基准测试,然后调用析构函数。所以输出看起来像

Constructor
Constructor
.. (benchmarking outputs)..
Destroy collection                                                                              
Destroy collection

这最终会花费太多时间来多次读取(相同的)文件,并且还会占用额外的内存来保存多个基准测试的相同数据。我也担心结果是否会受到页面错误的影响。因此,我有两个问题:

  1. 有没有办法避免读取文件两次,因为它可以节省一些执行时间(尽管这段时间不计入基准测试)。
  2. (如果不是)如何以每个基准调用构造函数、执行基准测试、破坏然后继续下一个基准测试的方式重组多个基准测试代码?(当然不必使用多个main功能)

更新 1

我需要注册的基准是不同的。我不希望将不同的参数传递给相同的基准。我已经用Build1和相应地更新了这个问题Build2

4

1 回答 1

0

如果您定义自己的main,则可以创建一个全局集合并从每个基准测试中引用它。

但是,您也可以通过只注册一次基准来避免此问题:

BENCHMARK_REGISTER_F(BuildFixture, Build)->Arg(10)->Arg(20)
于 2020-03-13T14:14:14.910 回答