必须选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++ 标准只说“尽可能高精度”,但没规定是否 steady;GCC 和 MSVC 都把它 alias 到steady_clock,Clang 在某些旧版本却 alias 到system_clock,一跑就翻车 - 实测:在 macOS 13 + Clang 14 下,
high_resolution_clock::is_steady返回false,而steady_clock::is_steady恒为true
最简可靠写法(含误差说明)
用 time_point 记起点和终点,用 duration_cast 转成微秒——注意不是所有平台都能精确到 1μs,实际分辨率取决于硬件和 OS。
#include <chrono> #include <iostream> <p>auto start = std::chrono::steady_clock::now(); // ... your code here ... auto end = std::chrono::steady_clock::now();</p><p>auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count(); std::cout << "cost: " << us << " μs\n";
-
count()返回的是long long类型整数,不是浮点,避免隐式转换开销 - 不要用
duration_cast<double>:浮点运算慢,且对微秒级计时无意义(纳秒级才需小数) - 实际分辨率可查:
std::chrono::steady_clock::period::num / std::chrono::steady_clock::period::den,常见值是 1/1000000000(即 1ns),但真实抖动常在 10–100ns 量级
多次运行取最小值才接近真实开销
单次测量受上下文切换、TLB miss、CPU 频率升降等干扰太大,尤其代码很短时,测出来可能是 0 或几十微秒飘忽不定。
立即学习“C++免费学习笔记(深入)”;
- 至少循环 100 次以上,记录每次耗时,取
min—— 最小值最接近“纯代码执行开销”,排除了大部分系统噪声 - 加
asm volatile("" ::: "memory")防止编译器优化掉待测代码(特别是空循环或纯计算) - 若要压测吞吐,就用总时间除以次数;若要分析延迟下界,就盯住最小值
真正难的不是调用 steady_clock::now(),而是判断哪段代码该被包进去、要不要预热、是否关掉了 CPU Turbo Boost —— 这些细节不控,微秒数字再漂亮也没参考价值。


















