用std::chrono计算毫秒差应调用std::chrono::duration_cast(end - start).count(),使用long long防溢出;测执行时间必须用steady_clock而非system_clock;单位转换必须显式cast,不可依赖count()猜测单位。

怎么用 std::chrono 算两个时间点的毫秒差
直接用 std::chrono::duration_cast 转换,别手算纳秒除 1e6 —— 容易溢出或精度丢失。
常见错误是把 time_point 直接相减后强转 int,结果截断或符号错乱:
// ❌ 错误:隐式转换丢精度,且没指定单位 auto diff = end - start; int ms = diff.count(); // 可能是纳秒,也可能是微秒,看时钟类型 <p>// ✅ 正确:显式转成毫秒,用 long long 防溢出 auto ms = std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
- 必须用
duration_cast,不能靠.count()猜单位 -
count()返回的是“刻度数”,不是毫秒值;刻度单位取决于时钟(steady_clock通常是纳秒) - 返回类型默认是
long long,别用int接,尤其测长任务时容易溢出 - 如果只要整数毫秒,用
milliseconds;要带小数,转double再除:std::chrono::duration<double>(end - start).count()</double>
steady_clock 和 system_clock 该选哪个
测代码执行时间必须用 std::chrono::steady_clock,system_clock 会被系统时间调整干扰,导致差值为负或跳变。
典型场景:性能压测、函数耗时统计、超时控制。
立即学习“C++免费学习笔记(深入)”;
-
steady_clock单调递增,不受 NTP 同步、手动改系统时间影响 -
system_clock对应墙上时间,适合打日志时间戳,不适合算差值 - Windows 上
steady_clock底层常映射到QueryPerformanceCounter,Linux 上多为CLOCK_MONOTONIC,都够用 - 别混用:不同 clock 的
time_point不能直接相减,编译不过
为什么 duration_cast 有时结果是 0
不是代码写错了,是时间太短,低于目标单位的最小刻度 —— 比如实际耗时 500 纳秒,转 milliseconds 就是 0。
这是截断(truncation),不是四舍五入,duration_cast 默认向下取整。
- 检查原始差值:
(end - start).count()看是不是真的在纳秒级 - 需要亚毫秒精度就换单位:
microseconds或nanoseconds - 想四舍五入?得自己加半格再 cast:
duration_cast<milliseconds>(diff + 500us)</milliseconds> - Release 模式下空循环可能被优化掉,测不准——记得用 volatile 或防止优化的 trick
跨平台编译时 chrono 行为不一致怎么办
主要差异在分辨率和起始点,但 duration_cast 语义是标准的,只要不用 .time_since_epoch().count() 硬解,基本不会翻车。
容易踩的坑是依赖绝对时间值,比如把 time_point 存成整数传给 C API。
- 永远用相对差值,别碰
time_since_epoch的原始值 - 避免用
system_clock::to_time_t做中间转换,Windows 和 Linux 对闰秒处理不同 - Clang/GCC/MSVC 对
steady_clock::now()的实现延迟略有差异,但误差都在微秒级,不影响毫秒级测量 - 如果要序列化时间差,只存
duration.count()和单位(比如“ms”),别存time_point
最常被忽略的一点:steady_clock::now() 本身有开销,约几十纳秒。测极短函数(比如几条指令)时,这个开销占比不可忽视,得跑多次取中位数或用基准测试框架对消。









