最可靠方案是用 std::chrono::high_resolution_clock:它跨平台、纳秒级精度、无运行时开销,且避免 system_clock 的时间跳变问题;需确保时钟类型一致、Release 编译,并验证 is_steady 和 period::den。

用 std::chrono 测单次执行耗时最可靠
Windows 上用 GetTickCount64 或 Linux 用 clock_gettime(CLOCK_MONOTONIC, ...) 虽然快,但跨平台麻烦、精度不一;std::chrono 是 C++11 起的标准方案,底层自动调用高精度时钟(如 Windows 的 QueryPerformanceCounter),精度通常在纳秒级,且语义清晰。
常见错误是用 std::clock()——它测的是 CPU 时间,多线程或系统调度下严重失真;还有人用 time(NULL),秒级精度根本不够。
实操建议:
- 统一用
std::chrono::high_resolution_clock(多数实现即系统最高精度时钟) - 起止时间必须用同一时钟类型,避免隐式转换误差
- 测量短任务时,重复多次取平均,单次可能受缓存预热、分支预测等干扰
auto start = std::chrono::high_resolution_clock::now(); do_something(); auto end = std::chrono::high_resolution_clock::now(); auto us = std::chrono::duration_cast<std::chrono::microseconds>(end - start).count();
别直接用 std::chrono::system_clock 测性能
std::chrono::system_clock 对应系统时间(即墙上时间),会受 NTP 校时、手动改系统时间影响,跳变或回退会导致差值为负或巨大异常值。它适合打日志时间戳,不适合性能计时。
立即学习“C++免费学习笔记(深入)”;
容易踩的坑:
- 误以为 “high_resolution” 是修饰 system_clock 的——其实
std::chrono::high_resolution_clock是独立类型,和system_clock无关 - 在跨进程/跨机器场景下,想用 system_clock 对齐时间,结果发现精度不足还易漂移
- 某些旧编译器(如 GCC 4.8 前)里
high_resolution_clock可能退化为system_clock,需运行时验证
Release 模式下 std::chrono 无运行时开销
有人担心计时代码拖慢程序,其实 std::chrono::now() 编译后就是几条汇编指令(如 RDTSC 或系统调用封装),Release 下内联彻底,没函数调用成本。Debug 模式下可能略慢,但那是调试本身的问题,不是 chrono 的锅。
关键点:
- 计时本身不触发内存分配、不抛异常、不依赖 STL 容器
- 但如果你把
std::chrono::duration_cast结果转成std::string打日志,那开销就全在字符串操作上了 - 频繁调用(比如每帧都测)要注意时钟读取本身也有微小延迟,高频场景可考虑采样或硬件计数器(如 perf_event_open)
Windows 上 MinGW 与 MSVC 的 high_resolution_clock 行为差异
MinGW-w64 默认用 gettimeofday 模拟,精度卡在毫秒级;MSVC 则直通 QueryPerformanceCounter,稳稳纳秒级。这不是 bug,是工具链实现选择不同。
解决办法很实际:
- 检查
std::chrono::high_resolution_clock::is_steady返回 true 再用(确保单调不跳变) - 用
std::chrono::high_resolution_clock::period::den看分母,大于 1e9 就说明达不到纳秒精度 - 若必须高精度且用 MinGW,可临时切到
std::chrono::steady_clock(部分版本更准),或直接调QueryPerformanceCounter
真正复杂的地方在于:你写的计时逻辑可能在 CI、容器、WSL 里跑,而这些环境的时钟源各不相同,光靠标准库无法 100% 保证精度一致。得结合具体部署环境做校准。










