0

0

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

尼克

尼克

发布时间:2026-01-15 16:12:43

|

261人浏览过

|

来源于php中文网

原创

用 std::chrono::high_resolution_clock::now() 获取高精度时间点,性能测量只存 time_point,用 duration_cast 转换差值,转本地时间需经 system_clock 中转。

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

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

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

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

  • 不要写 auto t = std::chrono::system_clock::now(); 测耗时
  • 避免在循环里反复调用 .time_since_epoch().count() ——先存 time_point,结束再算差值
  • 跨线程测量时注意:不同 CPU 核心的 high_resolution_clock 可能有微小漂移,短于 1μs 的测量慎用

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

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:

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

  • auto ms_rounded = std::chrono::duration_cast<:chrono::milliseconds>(end - start + 500μs);
  • 用字面量后缀(msusns)比写 std::chrono::milliseconds(1) 更简洁且不易错
  • 别对 duration 做浮点运算后再 cast——double 表示大整数时会丢失精度(比如超过 2⁵³ 的纳秒值)

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

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

豆包手机助手
豆包手机助手

豆包推出的手机系统服务级AI助手

下载
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() 打日志。

  • 别试图用 high_resolution_clock::to_time_t(tp) ——标准没定义它的行为
  • std::put_time 需要 C++11 以上且编译器支持,MSVC 2015+、GCC 5+、Clang 3.7+ 没问题
  • 多线程下 std::localtime 不安全,应改用 std::localtime_r(POSIX)或 std::localtime_s(MSVC)

为什么 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);
  • steady_clock 的精度不一定比 high_resolution_clock 低——现代 Linux 上两者常是同一实现
  • 检查是否真的单调:std::chrono::steady_clock::is_steady 返回 true 才放心用
  • 不要混用 clock 类型:steady_clock::time_pointsystem_clock::time_point 之间不能直接相减

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

相关专题

更多
counta和count的区别
counta和count的区别

Count函数用于计算指定范围内数字的个数,而CountA函数用于计算指定范围内非空单元格的个数。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

197

2023.11.20

js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

256

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

208

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

1465

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

619

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

550

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

545

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

161

2025.07.29

Golang gRPC 服务开发与Protobuf实战
Golang gRPC 服务开发与Protobuf实战

本专题系统讲解 Golang 在 gRPC 服务开发中的完整实践,涵盖 Protobuf 定义与代码生成、gRPC 服务端与客户端实现、流式 RPC(Unary/Server/Client/Bidirectional)、错误处理、拦截器、中间件以及与 HTTP/REST 的对接方案。通过实际案例,帮助学习者掌握 使用 Go 构建高性能、强类型、可扩展的 RPC 服务体系,适用于微服务与内部系统通信场景。

8

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
PostgreSQL 教程
PostgreSQL 教程

共48课时 | 7.2万人学习

Git 教程
Git 教程

共21课时 | 2.7万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号