用std::chrono::high_resolution_clock测毫秒需用duration_cast<std::chrono::milliseconds>转换,不可依赖.count()或除法;它测墙上时间,而clock()测CPU时间且精度低;steady_clock更稳妥;单次测量易受噪声影响,应循环多次。

用 std::chrono::high_resolution_clock 测毫秒要小心时钟类型转换
直接用 high_resolution_clock 的 time_point 相减,得到的是 duration,但它的底层单位不固定(可能是纳秒、微秒,甚至在某些旧编译器里是毫秒),不能假设 .count() 返回的就是毫秒数。
正确做法是显式转换到毫秒精度的 duration:
auto start = std::chrono::high_resolution_clock::now(); // ... your code ... auto end = std::chrono::high_resolution_clock::now(); auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
- 必须用
duration_cast,不能靠除法手动换算(会丢失精度或引入整数截断) -
std::chrono::milliseconds是带符号整型 duration,适合大多数场景;若需更高精度,可用std::chrono::microseconds或std::chrono::nanoseconds - 某些嵌入式或老版本 libstdc++(如 GCC 4.8)中
high_resolution_clock可能退化为system_clock,实测分辨率只有 10–15ms,建议先打印start.time_since_epoch().count()看量级
别用 std::clock() 测代码段耗时
std::clock() 返回的是 CPU 时间,不是真实经过时间(wall-clock time),对多线程、IO 等待、系统调度不敏感,且在 Windows 上分辨率极差(常为 10–15ms),Linux 上也受限于 CLOCKS_PER_SEC(通常 1e6,但实际精度未必达标)。
- 它测的是当前进程占用 CPU 的总时间,如果代码段里有
sleep、read、wait,结果会严重偏低 -
clock()在多线程下行为未定义,C++11 后已不推荐用于性能测量 - 想对比的话:同一段含
std::this_thread::sleep_for(100ms)的代码,clock()可能返回接近 0,而high_resolution_clock稳定返回 ~100
Windows 下 QueryPerformanceCounter 和 high_resolution_clock 的关系
MSVC 的 std::chrono::high_resolution_clock 底层就是封装的 QueryPerformanceCounter(QPC),所以无需手动调用 Win32 API —— 除非你明确需要 QPC 的特殊保证(比如跨休眠/挂起的连续性,或绕过某些虚拟机时钟漂移问题)。
立即学习“C++免费学习笔记(深入)”;
- 普通应用直接用
high_resolution_clock更安全,它自动处理频率换算和溢出 - 手动用 QPC 要自己调
QueryPerformanceFrequency,再做浮点除法,容易因 double 精度丢失导致毫秒级误差(尤其在长时间运行后) - Clang/LLVM on Windows(如 MinGW-clang)可能用不同实现,
high_resolution_clock::is_steady值更值得检查
高频短代码段测量容易被噪声淹没
单次 high_resolution_clock::now() 调用本身耗时约 10–100ns(取决于 CPU 和内核状态),如果你测的代码段本身就只跑几十纳秒,结果就不可信。
- 务必循环多次(如 1e4–1e6 次),再除以次数,否则标准差可能比均值还大
- 注意编译器优化:加
volatile或用asm volatile("" ::: "memory")防止空循环被优化掉 - 用
std::chrono::steady_clock替代high_resolution_clock更稳妥 —— 它不回跳、不被 NTP 调整,且多数平台分辨率足够(通常也是纳秒级) - 真实耗时还受 CPU 频率动态调整(Intel SpeedStep / AMD Cool'n'Quiet)、缓存预热、TLB miss 等影响,单次测量意义有限
高精度计时真正难的不是写那几行 now() 和 duration_cast,而是搞清你要测的是什么:CPU 时间?墙上时间?是否包含系统调用?要不要排除编译器优化干扰?这些决定了该选哪个 clock、要不要循环、要不要绑核。


















