std::chrono::steady_clock是c++11起为性能测量明确定义的首选时钟,它保证单调且稳定,比high_resolution_clock更可靠;推荐用raii封装timer类并默认以纳秒为单位。

std::chrono::high_resolution_clock 真的够高精度吗?
在大多数现代系统上,std::chrono::high_resolution_clock 是当前可用的最高精度时钟,但它不保证是单调的(某些平台可能回退),也不一定对应“墙上时间”。Linux 上它通常映射到 CLOCK_MONOTONIC,Windows 上对应 QueryPerformanceCounter —— 这两点决定了它适合测耗时,但不适合做绝对时间戳。
- 别用
system_clock测运行时间:它可能受系统时间调整影响,导致计时跳变甚至倒流 - 别假设
high_resolution_clock::period::den是纳秒:实际分辨率因平台而异,steady_clock更推荐用于耗时测量(它明确保证单调且稳定) - 实操建议:直接用
std::chrono::steady_clock,它是 C++11 起为性能测量明确定义的首选
怎么写一个靠谱的函数封装?
手写两次 steady_clock::now() 再相减太容易出错,尤其漏掉 duration_cast 会编译失败或隐式截断。封装成 RAII 风格最稳。
class Timer {
using clock = std::chrono::steady_clock;
clock::time_point start_;
public:
Timer() : start_(clock::now()) {}
template<typename Unit = std::chrono::nanoseconds>
long long elapsed() const {
return std::chrono::duration_cast<Unit>(clock::now() - start_).count();
}
};- 返回
long long而非auto:避免模板推导出意外类型(比如double或低精度整型) - 默认单位设为
nanoseconds:比milliseconds更少丢失精度,后续按需转成毫秒/微秒也方便 - 构造即记录起点:避免手动调用
now()时机偏差,比如构造后隔了几行才开始干活
为什么 duration_cast 之后 count() 值突然变小了?
这不是 bug,是整数截断行为。比如你用 nanoseconds 计算得到 1234567 纳秒,再用 duration_cast<milliseconds></milliseconds> 后调 count(),结果是 1(不是 1.234)。C++ 的 duration_cast 默认向下取整,不四舍五入。
- 要保留小数毫秒显示?别用
count(),改用浮点类型转换:std::chrono::duration<double std::milli>(end - start).count()</double> - 想四舍五入到毫秒?先转成纳秒再加 500000,再 cast:
std::chrono::duration_cast<:chrono::milliseconds>(ns + std::chrono::nanoseconds(500000)).count()</:chrono::milliseconds> - 注意:频繁用浮点
duration可能引入精度误差,生产环境计时统计优先用整数纳秒+后期聚合
多线程里用 steady_clock 安全吗?
安全。每个线程调用 steady_clock::now() 都是独立的,没有共享状态,也不依赖线程本地存储。但要注意——如果你把一个 Timer 对象跨线程传递(比如构造在线程 A,elapsed() 在线程 B 调用),没问题;但若多个线程并发读写同一个 Timer 实例(比如反复调用 reset()),就得加锁。
立即学习“C++免费学习笔记(深入)”;
- 典型误用:全局单例
Timer被多个线程同时调用elapsed()并修改内部状态 - 更轻量做法:每个线程用栈上
Timer,或者用thread_local static Timer t;避免锁 - 别依赖
high_resolution_clock::is_steady:它只是个静态 constexpr 值,不能替代运行时行为验证
精度本身不难控制,难的是统一单位、规避整数截断、以及跨线程时对“对象生命周期”的直觉误判。








