最可靠方式是用 std::chrono::high_resolution_clock 配合 duration_cast;它底层调用系统高精度计时器,精度远超 GetTickCount64() 和 clock(),且跨平台、防优化、可测真实耗时。

用 std::chrono 测单次执行耗时最可靠
Windows 上用 GetTickCount64() 或旧式 clock() 容易翻车,前者精度只有 10–16ms,后者还受 CLOCKS_PER_SEC 限制(Linux 常为 100 万,但 Windows 是 1000),测短任务基本不准。C++11 起 std::chrono 是唯一推荐路径,底层对接系统高精度计时器(如 Windows 的 QueryPerformanceCounter,Linux 的 clock_gettime(CLOCK_MONOTONIC))。
实操建议:
- 固定用
std::chrono::high_resolution_clock—— 不要写成steady_clock或system_clock,前者是标准里“最高可用精度”的保证,后两者不承诺精度 - 时间差必须用
duration_cast显式转,比如std::chrono::nanoseconds,直接 .count() 会返回未指定单位的整数,容易误读 - 别在循环里反复调用
now()测函数内联开销——现代编译器可能优化掉,真要压测得关优化(-O0)或加volatile防止误判
auto start = std::chrono::high_resolution_clock::now(); do_work(); auto end = std::chrono::high_resolution_clock::now(); auto ns = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count();
测多轮平均耗时要防编译器优化和缓存干扰
单纯跑一次 now() 差值,对微秒级函数意义不大;真实场景需要多次运行取平均,但这时编译器可能把循环整个优化掉,或者 CPU 缓存让后续迭代快得离谱,数据失真。
常见错误现象:
立即学习“C++免费学习笔记(深入)”;
- 开启
-O2后,空循环测出来是 0ns —— 因为编译器发现没副作用,直接删了 - 连续跑 1000 次
sqrt(42.0),第一次 50ns,后面全 1ns —— L1 缓存+分支预测全就位,不代表真实负载
实操建议:
- 用
volatile强制读写内存(比如把结果存到volatile double result),阻止编译器削除计算 - 每次迭代前加
std::atomic_thread_fence(std::memory_order_seq_cst),防止指令重排干扰起点 - 真正压测时,先热身 10–20 次再计时,跳过冷启动抖动
跨平台精度差异:Windows 和 Linux 的 high_resolution_clock 实际表现不同
标准只说它是“最高可用精度”,没规定具体值。Windows 下 high_resolution_clock::period::den 通常是 10⁷(即 100ns 级),Linux 下常为 10⁹(1ns 级),但实际分辨率还取决于硬件和内核配置。别硬编码假设 1ns 精度。
使用场景:
- 做性能对比(A 函数比 B 快多少)—— 只要同平台、同编译器,相对值可信
- 写 benchmark 库或 CI 耗时断言 —— 必须运行时查
high_resolution_clock::period::num / period::den,按实际精度设容差(比如误差 > 3 倍最小刻度就报警) - 日志打点记耗时 —— 直接用
microseconds就够,人眼根本看不出 100ns 和 200ns 区别
别用 std::clock() 测 wall-clock 时间
std::clock() 返回的是进程**CPU 时间**,不是真实流逝时间。多线程下它只累加当前线程占用的 CPU 片段,sleep、IO 等待、其他线程干活都不算进去。测网络请求或磁盘读写,它可能报 0ms,纯误导。
典型错误:
- 写
auto t0 = clock(); sleep(1000); auto t1 = clock();,结果t1-t0接近 0 —— 因为 sleep 不消耗 CPU - 用它判断算法“快慢”,但实际程序卡在锁或系统调用上,
clock()完全不反映
替代方案就一个:std::chrono::high_resolution_clock。哪怕只是想粗略看秒级耗时,也用 std::chrono::steady_clock::now(),它至少保证单调递增且测的是真实时间。
真正难的不是选哪个 API,而是理解你到底想测什么:是 CPU 算力瓶颈?还是端到端延迟?或是某段代码在特定负载下的稳定性?选错目标,再准的计时器也白搭。










