kfm*_*e04 14 c++ benchmarking googletest
我有一个运行三种状态的模拟器:
有没有搞错! 在标准测试期间,CPU使用率从100%下降到20%,总运行时间比正常时间长30倍(130秒与4.2秒).
当Callgrind没有发现任何可疑的事情时,我的头嗡嗡作响,因为我正在回到最后一次提交的悬崖上,失去了所有的错误修复.
气馁,我在跑步期间走进服务器机房,注意到讨厌的磨音,后来验证是由于/ proc/PID/fd中的 Mysql套接字写入造成的!事实证明,第2阶段深层的几层Mysql代码导致了问题.
得到教训
修复 我将在ReadAllowed()和WriteAllowed()上引入线程本地存储IOSentinels和asserts(),以确保Stage 2线程永远不会执行任何IO.
任何人都有幸与googletest附加/编写基准测试框架?
不幸的是,这次我的所有googletests都通过了.如果我稍稍离开并在没有注意到运行时间的情况下回来,这将是一个灾难性的提交,并且可能更难修复.
如果运行时间超过上次运行时的2或3倍,我希望googletest失败:这最后一部分很棘手,因为对于非常快速的运行,系统状态可能导致某些事情需要两倍的时间但仍然可以.但是对于长时间的模拟运行/测试,我不希望运行时间变化很大(> 50%会不常见).
我对这里的建议持开放态度,但是对于自动化测试进行低维护检查会很好,所以即使所有输出看起来都没问题,系统突然变慢也很明显.
我在 v1.5.0 中这样做:
BENCHMARK(SomeBenchmark);
BENCHMARK(AnotherBenchmark);
TEST(MyTest, Benchmarks)
{
::benchmark::RunSpecifiedBenchmarks();
}
Run Code Online (Sandbox Code Playgroud)
也就是说,我只是在 gtest 测试之一中直接调用 RunSpecifiedBenchmarks。
是不是就这么简单呢?
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)
但我想知道这种额外的复杂性是否真的合理。