C++怎么算时间差 C++中chrono库高精度计时【手册】

2次阅读

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

C++怎么算时间差 C++中chrono库高精度计时【手册】

怎么用 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_clocksystem_clock 该选哪个

测代码执行时间必须用 std::chrono::steady_clocksystem_clock 会被系统时间调整干扰,导致差值为负或跳变。

典型场景:性能压测、函数耗时统计、超时控制。

立即学习C++免费学习笔记(深入)”;

  • steady_clock 单调递增,不受 NTP 同步、手动改系统时间影响
  • system_clock 对应墙上时间,适合打日志时间戳,不适合算差值
  • windowssteady_clock 底层常映射到 QueryPerformanceCounterlinux 上多为 CLOCK_MONOTONIC,都够用
  • 别混用:不同 clock 的 time_point 不能直接相减,编译不过

为什么 duration_cast 有时结果是 0

不是代码写错了,是时间太短,低于目标单位的最小刻度 —— 比如实际耗时 500 纳秒,转 milliseconds 就是 0。

这是截断(truncation),不是四舍五入,duration_cast 默认向下取整。

  • 检查原始差值:(end - start).count() 看是不是真的在纳秒级
  • 需要亚毫秒精度就换单位:microsecondsnanoseconds
  • 想四舍五入?得自己加半格再 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() 本身有开销,约几十纳秒。测极短函数(比如几条指令)时,这个开销占比不可忽视,得跑多次取中位数或用基准测试框架对消。

text=ZqhQzanResources