使用googletest进行基准测试?

kfm*_*e04 14 c++ benchmarking googletest

背景(如果不感兴趣,请跳至下面的问题)

我有一个运行三种状态的模拟器:

  1. 单线程启动(I/O ok)
  2. 多线程内存CPU绑定仿真阶段(I/O不行)
  3. 后仿真,后连接单线程阶段(I/O ok)

有没有搞错! 在标准测试期间,CPU使用率从100%下降到20%,总运行时间比正常时间长30倍(130秒与4.2秒).

Callgrind没有发现任何可疑的事情时,我的头嗡嗡作响,因为我正在回到最后一次提交的悬崖上,失去了所有的错误修复.

气馁,我在跑步期间走进服务器机房,注意到讨厌的磨音,后来验证是由于/ proc/PID/fd中的 Mysql套接字写入造成的!事实证明,第2阶段深层的几层Mysql代码导致了问题.

得到教训

  1. 意外I/O对于实时应用程序可能是致命的
  2. 单元测试还不够:我也需要基准测试

修复 我将在ReadAllowed()和WriteAllowed()上引入线程本地存储IOSentinels和asserts(),以确保Stage 2线程永远不会执行任何IO.

任何人都有幸与googletest附加/编写基准测试框架?

不幸的是,这次我的所有googletests都通过了.如果我稍稍离开并在没有注意到运行时间的情况下回来,这将是一个灾难性的提交,并且可能更难修复.

如果运行时间超过上次运行时的2或3倍,我希望googletest失败:这最后一部分很棘手,因为对于非常快速的运行,系统状态可能导致某些事情需要两倍的时间但仍然可以.但是对于长时间的模拟运行/测试,我不希望运行时间变化很大(> 50%会不常见).

我对这里的建议持开放态度,但是对于自动化测试进行低维护检查会很好,所以即使所有输出看起来都没问题,系统突然变慢也很明显.

Dan*_* V. 5

我在 v1.5.0 中这样做:

BENCHMARK(SomeBenchmark);
BENCHMARK(AnotherBenchmark);

TEST(MyTest, Benchmarks)
{
    ::benchmark::RunSpecifiedBenchmarks();
}
Run Code Online (Sandbox Code Playgroud)

也就是说,我只是在 gtest 测试之一中直接调用 RunSpecifiedBenchmarks。


nod*_*kai 3

是不是就这么简单呢?

const clock_t t0 = clock(); // or gettimeofday or whatever
int res = yourFunction();
const clock_t t1 = clock();
const double elapsedSec = (t1 - t0) / (double)CLOCKS_PER_SEC;
EXPECT_EQ(EXPECTED, res);
EXPECT_GT(10.0, elapsedSec);
Run Code Online (Sandbox Code Playgroud)

这里,您需要10.0根据您的任务手动更改。

当然,你还可以更进一步,比如:

double prev = -1;
{
  ifstream ifs("/var/tmp/time_record.txt");
  ifs >> prev;
}
if (prev < 0) prev = DEFAULT_VALUE;
// ...
EXPECT_GT(2 * prev, elapsedSec);
{
  ofstream ofs("/var/tmp/time_record.txt");
  ofs << elapsedSec << endl;
}
Run Code Online (Sandbox Code Playgroud)

但我想知道这种额外的复杂性是否真的合理。

  • 或者,如果可能的话,使用 C++11 中的 std::chrono 库。googletest 库在编译 C++11 时也能正常工作。 (2认同)