在C++中,经常需要通过计时来统计性能信息,通过统计的耗时信息,来分析性能瓶颈,通常情况下,可能毫秒级别的时间统计就足够用了,但是在毫厘必争的性能热点的地方,毫秒级别的统计还是不够的,这种情况下,就需要至少微秒级别的统计信息,甚至要精确到CPU的指令周期级别。下面来重点说一下毫秒级的计时统计信息。
毫厘必争--微秒计时思路
在Windows平台上,用来统计微秒级别耗时信息,需要用到两个Windows API:
BOOL WINAPI QueryPerformanceFrequency( _Out_ LARGE_INTEGER *lpFrequency ); BOOL WINAPI QueryPerformanceCounter( _Out_ LARGE_INTEGER *lpPerformanceCount );
QueryPerformanceFrequency用于获取性能计数的频率,每秒多少次,
QueryPerformanceCounter用于获取当前性能计数的值,
有了这两个API,我们就可以用来统计耗时了,思路如下:
那么如何得到最终的耗时呢,相信不难回答,公式如下:
秒级耗时 = (结束性能计数值 - 开始性能计数值) / 性能计数频率 微秒耗时 = (结束性能计数值 - 开始性能计数值)* 1000000 / 性能计数频率
微秒计时实现
LARGE_INTEGER freq_; QueryPerformanceFrequency(&freq_); LARGE_INTEGER begin_time; LARGE_INTEGER end_time; QueryPerformanceCounter(&begin_time); Sleep(100); QueryPerformanceCounter(&end_time); double ns_time = (end_time.QuadPart - begin_time.QuadPart) * 1000000.0 / freq_.QuadPart;
封装微秒计时的实现
虽然上面已经实现了微秒精度计时,但是由于每次调用API时,都要定义变量等,使用起来肯定会有很多重复或者类似的代码,那么为了避免这种情况,对此实现进行了封装,如下:
class stop_watch { public: stop_watch() : elapsed_(0) { QueryPerformanceFrequency(&freq_); } ~stop_watch(){} public: void start() { QueryPerformanceCounter(&begin_time_); } void stop() { LARGE_INTEGER end_time; QueryPerformanceCounter(&end_time); elapsed_ += (end_time.QuadPart - begin_time_.QuadPart) * 1000000 / freq_.QuadPart; } void restart() { elapsed_ = 0; start(); } //微秒 double elapsed() { return static_cast<double>(elapsed_); } //毫秒 double elapsed_ms() { return elapsed_ / 1000.0; } //秒 double elapsed_second() { return elapsed_ / 1000000.0; } private: LARGE_INTEGER freq_; LARGE_INTEGER begin_time_; long long elapsed_; };
那么,如何使用此封装的类呢,来看一下调用的例子:
stop_watch watch; watch.start(); Sleep(100); watch.stop(); cout << watch.elapsed() << " ns" << endl;
看看调用是不是更方便了呢,是不是有点似曾相识的感觉,对,没错,你猜对了。。。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?