std::chrono::high_resolution_clock 是标准库中唯一能稳定提供微秒级(甚至纳秒级)精度的时钟,需用 duration_cast<std::chrono::microseconds> 转换才能获得微秒整数,且结果为截断而非四舍五入。

用 std::chrono::high_resolution_clock 获取微秒级时间点
标准库里能稳定提供微秒级(甚至纳秒级)精度的只有 std::chrono::high_resolution_clock。它不保证是单调时钟,但在绝大多数现代系统(Linux/Windows/macOS)上底层调用的是高精度计时器(如 CLOCK_MONOTONIC 或 QueryPerformanceCounter),实际可用。别用 std::chrono::system_clock —— 它可能被系统时间调整干扰,也不一定够快。
获取时间点只需一行:
auto start = std::chrono::high_resolution_clock::now();
注意:now() 返回的是 time_point 类型,不是整数,不能直接相减出微秒值 —— 得转。
用 duration_cast 转成微秒整数
两个 time_point 相减得到的是 duration,但默认单位取决于时钟实现(通常是纳秒)。要得到微秒整数,必须显式转换:
立即学习“C++免费学习笔记(深入)”;
auto start = std::chrono::high_resolution_clock::now(); // ... 一些操作 auto end = std::chrono::high_resolution_clock::now(); auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
关键点:
组合式C++代码评审方案,融合静态分析、AI推理、多轮迭代评审和C++专项检查,适用于PR审查、增量代码审查、全项目评审和代码质量评分,触发词包括review cpp、cpp代码评审、C++review、代码审查。
-
duration_cast是截断(truncating),不是四舍五入 —— 比如 1234.9 纳秒 → 1 微秒 - 如果想保留小数微秒(如 1.234 µs),用
std::chrono::duration<double, std::micro>,但.count()会返回double - 别用
auto us = (end - start).count()—— 这拿到的是纳秒(或更小单位),数值大且不可移植
跨线程或长间隔时要注意时钟稳定性
high_resolution_clock 在单次测量中足够准,但不等于“绝对可靠”:
- 在某些旧内核或虚拟机里,它的周期性抖动可能达几十微秒
- 如果两次
now()调用跨越了 CPU 频率切换(如节能模式)、进程被抢占超过毫秒级,测得的差值就包含调度开销,不是纯代码耗时 - 连续多次测量建议取中位数,而不是平均值 —— 防止某次被中断打歪
简单性能采样可以这样写:
std::vector<int64_t> samples;
for (int i = 0; i < 5; ++i) {
auto t0 = std::chrono::high_resolution_clock::now();
do_work();
auto t1 = std::chrono::high_resolution_clock::now();
samples.push_back(std::chrono::duration_cast<std::chrono::microseconds>(t1 - t0).count());
}
std::sort(samples.begin(), samples.end());
int64_t median_us = samples[samples.size() / 2];
Windows 上 QueryPerformanceCounter 的兼容性坑
如果你在 Windows 上用 MinGW 或较老 MSVC(high_resolution_clock::now() 可能退化为毫秒级(基于 GetTickCount)。此时应手动用 QueryPerformanceCounter:
LARGE_INTEGER freq, start, end; QueryPerformanceFrequency(&freq); QueryPerformanceCounter(&start); do_work(); QueryPerformanceCounter(&end); int64_t us = (end.QuadPart - start.QuadPart) * 1000000LL / freq.QuadPart;
这个写法绕过 STL 实现缺陷,但只适用于 Windows。跨平台项目仍推荐优先用 std::chrono,并在 CI 中验证其分辨率(比如跑一次 now() 调用 1000 次,看最小非零差值是否 ≤1µs)。
真正难的不是算差值,而是确认你拿到的那个“微秒”,确实是你要测的那段逻辑花的时间 —— 调度、缓存预热、编译器优化都可能让它失真。测之前先关掉超线程、固定 CPU 频率、用 volatile 防优化,这些细节比选对函数更重要。

















