必须用 std::chrono::steady_clock 测耗时,因其不随系统时间调整跳变,Windows 用 QueryPerformanceCounter、Linux 用 CLOCK_MONOTONIC,防抖稳定;system_clock 可能回拨致负值,high_resolution_clock 行为跨平台不保证。

直接用 std::chrono::steady_clock,别碰 system_clock 或 high_resolution_clock —— 前者可能跳变,后者行为不保证跨平台稳定。
为什么必须选 steady_clock
它不随系统时间调整而跳变,也不受 NTP 同步、时区切换影响,是唯一适合测耗时的时钟。Windows 上它底层是 QueryPerformanceCounter,Linux 上通常是 CLOCK_MONOTONIC,天然防抖。
-
system_clock:可能回拨(比如手动改系统时间),导致duration为负 -
high_resolution_clock:C++ 标准只说“尽可能高精度”,但实际可能是system_clock的别名(GCC 常见),不可靠 - 只要目标是“代码块执行耗时”,
steady_clock就是唯一合理选择
最简可靠的微秒计时写法
别封装成类或宏——容易隐式拷贝、生命周期出错;用 RAII 方式局部定义 + duration_cast 转换,一行初始化、一行算差值。
#include <chrono> #include <iostream> <p>auto start = std::chrono::steady_clock::now(); // ... 你的代码块 auto end = std::chrono::steady_clock::now(); auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); std::cout << "耗时: " << us << " μs\n";
- 不用
auto diff = end - start再 cast:避免中间类型推导错误(比如误推成nanoseconds导致溢出) - 显式用
duration_cast<microseconds></microseconds>:确保单位明确,且.count()返回long long,不会被截断 - 不要用
time_since_epoch():多此一举,且在某些平台(如 macOS)可能精度损失
高频调用时要注意的性能坑
steady_clock::now() 不是免费的——x86-64 上通常需 20–50 纳秒,频繁调用(比如循环内)会显著污染测量结果。
立即学习“C++免费学习笔记(深入)”;
- 单次测量:没问题,开销可忽略
- 想测函数平均耗时?用循环跑 N 次,只在循环外记 start/end,别在循环内反复调用
now() - 极端场景(如测纳秒级操作):考虑用
rdtsc指令(需校准、禁用频率缩放),但已脱离标准 C++ 范畴 - Clang/GCC 高优化下,编译器可能把空循环优化掉——加
asm volatile("" ::: "memory")防止误优化
跨平台兼容性与精度确认
不是所有平台都真能到微秒级精度。Linux 上 CLOCK_MONOTONIC 通常 1–15 ns,Windows 上 QueryPerformanceCounter 理论可达 ~100 ns,但实际分辨率取决于硬件和驱动。
- 运行时检查:用
steady_clock::period::num / steady_clock::period::den算出理论周期(例如1/1000000000表示纳秒级) - 实测验证:连续两次
now()相减,看最小非零值是多少(常为几十纳秒) - 别信文档写的“high resolution”——实测才是唯一依据
真正难的不是写对那几行代码,而是意识到:微秒级测量本身就有物理限制,时钟源、CPU 频率变化、上下文切换、缓存命中率都会扰动结果。拿一次测量值下结论,往往比不测还危险。



















