贝利信息

c++中如何使用chrono库_c++高精度时间测量与转换方法【详解】

日期:2026-01-15 00:00 / 作者:尼克
用 std::chrono::high_resolution_clock::now() 获取高精度时间点,性能测量只存 time_point,用 duration_cast 转换差值,转本地时间需经 system_clock 中转。

如何用 std::chrono 获取当前高精度时间点

直接用 std::chrono::high_resolution_clock::now() 是最常用也最可靠的方式,它返回一个 time_point,底层精度取决于系统(Linux 通常纳秒级,Windows 可能是 100ns 级)。别用 system_clock 做性能测量——它可能被系统时钟调整影响,测出来的时间差会跳变。

常见错误:把 now() 结果直接转成 time_t 或打印为字符串来“看时间”,这反而丢精度、加开销。性能测量阶段只该存 time_point,最后再统一转换。

如何计算两个时间点之间的毫秒/微秒差值

std::chrono::duration_cast 转换,不是手动除 1000 或 1000000。C++ 的 duration 类型自带单位语义,硬除会丢失类型安全,还容易因整数截断出错。

auto start = std::chrono::high_resolution_clock::now();
// ... do something ...
auto end = std::chrono::high_resolution_clock::now();

auto us = std::chrono::duration_cast(end - start); auto ms = std::chrono::duration_cast(end - start); std::cout << "cost: " << us.count() << " μs\n";

注意:duration_cast 默认向下取整(如 1.9ms → 1ms),若需四舍五入,得手动加半格再 cast:

如何把 time_point 转成可读的本地时间字符串

必须经过 system_clock 中转,因为 high_resolution_clock 不保证和日历时间对齐。直接用 high_resolution_clock::to_time_t 是未定义行为。

auto tp = std::chrono::high_resolution_clock::now();
auto sys_tp = std::chrono::system_clock::from_time_t(
    std::chrono::system_clock::to_time_t(
        std::chrono::time_point_cast(
            tp
        )
    )
);
auto tt = std::chrono::system_clock::to_time_t(sys_tp);
std::cout << std::put_time(std::localtime(&tt), "%Y-%m-%d %H:%M:%S");

这段代码看着绕,是因为 high_resolution_clock::time_pointsystem_clock::time_point 的 epoch(起始点)可能不同,不能直接 static_cast。实际项目中,如果只要“大致时间”,更稳妥的做法是测完耗时后,另起一次 system_clock::now() 打日志。

为什么 steady_clockhigh_resolution_clock 更适合性能测量

因为 steady_clock 保证单调递增、不受系统时间调整影响,而 high_resolution_clock 在某些平台(尤其是旧版 Windows)其实是 system_clock 的别名,一旦 NTP 同步或用户手动改系统时间,前后两次 now() 相减可能得到负值。

所以真正做 benchmark 或 latency 统计,优先用:

auto start = std::chrono::steady_clock::now();
// ... work ...
auto end = std::chrono::steady_clock::now();
auto ns = std::chrono::duration_cast(end - start);

实际写压测或延迟打点时,最容易忽略的是 clock 类型选择和 time_point 转换路径——这两处一错,整个测量就失去意义。