C++如何计算代码运行时间_C++中chrono库高精度计时教程【性能】

1次阅读

最稳妥的性能测试时钟是std::chrono::steady_clock,因其单调且不受系统时间调整影响;high_resolution_clock虽精度高但语义不如steady_clock明确;需用duration_cast转换time_point差值,避免直接使用count()或错误cast导致截断。

C++如何计算代码运行时间_C++中chrono库高精度计时教程【性能】

std::chrono::high_resolution_clock 获取真实运行时间

直接用 std::chrono::high_resolution_clock 是最稳妥的选择,它在绝大多数平台(linux/macOS/windows)上都映射到系统最高精度的单调时钟源。不要用 std::chrono::system_clock,它受系统时间调整影响,测性能会出错。

关键点:

  • high_resolution_clock::now() 返回的是一个 time_point,不能直接相减得秒数,必须用 duration_cast
  • 测量前建议调用一次 now() 预热,避免首次调用因缓存/TLB未命中带来偏差
  • 如果只测一次短操作,务必循环多次再取平均,单次 nanoseconds 级别可能被噪声淹没
auto start = std::chrono::high_resolution_clock::now(); // your code here auto end = std::chrono::high_resolution_clock::now(); auto ns = std::chrono::duration_cast(end - start).count();

为什么 std::chrono::steady_clock 更适合性能测试

steady_clock 是单调递增、不受系统时间修改干扰的时钟,c++11 起就保证其“稳定”,比 high_resolution_clock 语义更明确。虽然部分旧编译器(如 GCC 4.8)里它和 system_clock 同义,但现代标准下它才是性能测试的首选。

常见误用:

立即学习C++免费学习笔记(深入)”;

  • steady_clock::now().time_since_epoch().count() 当作绝对时间戳用——它只是自某个未指定起点的 tick 数,仅差值有意义
  • 线程共享 time_point 做比较——不同线程调用 now() 没问题,但若涉及 sleep 或调度延迟,需注意上下文一致性
  • microsecondsmilliseconds 直接 cast 短于 1ms 的耗时——会截断为 0,应先 cast 到 nanoseconds 再转浮点

windowsQueryPerformanceCounterchrono 的实际差异

在 Windows 上,high_resolution_clock 底层通常就是 QueryPerformanceCounter(QPC),两者精度一致(约 15–25 ns)。但手动调用 QPC 有额外风险:

  • QPC 在某些老旧 bios虚拟机中可能不稳(计数器跳变),而 chrono 实现已做兜底适配
  • QPC 返回的 LARGE_INTEGER 需配合 QueryPerformanceFrequency 手动换算,容易溢出或精度丢失
  • Clang/MSVC 对 chrono 的内联优化更好,实测开销比裸 QPC 低 1–2 个周期

除非你在写驱动或极端受限环境,否则没必要绕过 chrono

避免被编译器优化掉待测代码

这是最容易被忽略的问题:如果编译器发现你测的函数没有副作用,它可能整个删掉,导致测出 0ns。

解决方法(按优先级):

  • 把计算结果赋给 volatile 变量:volatile auto result = expensive_func();
  • asm volatile("" ::: "memory") 插入编译器屏障(GCC/Clang)
  • 将输入数据声明为 volatile,或从 std::cin 读取(仅调试用)
  • 关掉优化(-O0)只用于验证逻辑,不能代表真实性能

尤其注意:std::cout 不足以阻止优化,I/O 可能被延迟或缓冲,仍可能被裁剪。

text=ZqhQzanResources