🚀 优质资源分享 🚀
学习路线指引(点击解锁) | 知识定位 | 人群定位 |
---|---|---|
🧡 Python实战微信订餐小程序 🧡 | 进阶级 | 本课程是python flask+微信小程序的完美结合,从项目搭建到腾讯云部署上线,打造一个全栈订餐系统。 |
💛Python量化交易实战💛 | 入门级 | 手把手带你打造一个易扩展、更安全、效率更高的量化交易系统 |
阅读前注意
本文所有代码贴出来的目的是帮助大家理解,并非是要引导大家跟写,许多环境问题文件问题没有详细说明,代码也并不全面,达不到跟做的效果。建议直接阅读全文即可,我在最后会给出详细代码地址,对源代码细节更感兴趣的同学可以下载参考。
性能测试:使用日志
在c++中进行性能测试是令人头疼的问题,我们往往需要在数以千计的log中分析出性能瓶颈————找出最耗时的部分。而这部分工作是极其枯燥的:
首先,我们需要准备好一个计算时间的工具类,好在我们拥有std::chrono
,有了它我们就可计算出过程经历的时间。聪明的你或许会搞出这样一个东西:
//时间计量工具最简单的样子
class TimeTool {
public:
//desp 表示输出的日志 日志字符串中可能会用一些文本替换的方式输出时间
//例如 $ST 表示开始时间 $ET 表示结束时间 %DT 表示他们的差
//它很可能是这样的 “xxx cost time $DT, st = %ST et = $ET”
TimeTool(const std::string& desp);
//在析构时自动输出日志
~TimeTool();
}
哦!我觉得他已经足够好了,或许还可以改进,不过现在它能够完成最基本的任务了!
完了吗?当然没有,还有更多的工作要做,接下来最重要的是……
我们不得不在我们富有美感的代码中插入这些令人糟心的“探针”,说不定还会加上一连串的{},让本来漂亮的代码变得层层深入,令人头大不已!
我手头正好有一份代码:
void saveTheWorld() {
Hero h = makeHero("smalldy");
WorldList& wlist = findBadWorld();
World target;
int rank = 0;
for(auto & w : wlist) {
if(w.rank() > rank) {
target = w;
rank = w.rank();
}
}
hero.save(target);
}
哇,很好的故事不是吗?(并不,你只关心性能测试,却没发现英雄已经挂了!)
现在,我们要对此代码片段进行性能测试:
void saveTheWorld() {
TimeTool save\_function\_cost("函数saveTheWorld耗时 $DT");
{
TimeTool make\_hero\_cost("makeHero耗时 $DT");
Hero h = makeHero("smalldy");
}
{
TimeTool find\_world("findBadWorld耗时 $DT");
WorldList& wlist = findBadWorld();
}
World target;
int rank = 0;
{
TimeTool find\_rank("查询最危险的世界耗时 $DT");
for(auto & w : wlist) {
if(w.rank() > rank) {
target = w;
rank = w.rank();
}
}
}
{
TimeTool hero\_save("英雄耗时 $DT");
hero.save(target);
}
}
天哪!这简直糟糕透了!它甚至不能正确的运行,因为局部变量将在作用域结束后销毁,英雄还没上场,就已经魂归高天了。或许我们可以对TimeTool类加以改动,让他提供主动的计时结束函数,这样,我们就可以去掉该死的{},然后手动设置开始点和结束点了,当然,这样的话,就要书写更多的“探针”代码了。
好吧,假设我们已经完成了这样工作,我想聪明的你一定不想让我再贴一遍这些无意义的代码了,你一定能想象到新的时间工具会长成什么样子了。我们把它跑起来,就会得到一小串日志啦!
TimeTool make\_hero\_cost("makeHero耗时 200ms");
TimeTool find\_world("findBadWorld耗时 200ms");
TimeTool find\_rank("查询最危险的世界耗时 100ms");
TimeTool hero\_save("英雄耗时 1500ms");
函数saveTheWorld耗时 2000ms
我们清楚的看到性能