应使用 std::chrono::high_resolution_clock 精确测时,紧邻被测代码记录起止时间,避免 io 和日志干扰,用 duration_cast 转换单位,配合 volatile 防优化、预热及动态运行时长确保结果可靠。

用 std::chrono 高精度测单次运行时间
直接用 clock() 或 time() 测 C++ 代码耗时,误差常达 10ms 以上,根本没法算“平均毫秒数”。必须上 std::chrono::high_resolution_clock,它在主流平台(Linux/Windows/Clang/GCC)基本能到纳秒级分辨率,实际稳定到微秒级没问题。
关键不是“能不能”,而是怎么避免常见陷阱:
-
auto start = std::chrono::high_resolution_clock::now()和end必须在被测代码**紧邻前后**,中间别插日志、IO、变量声明——哪怕一行std::cout都会让结果失真 - 别用
std::chrono::system_clock:它可能受系统时间调整影响,测出来忽高忽低 - 别手动除 1'000'000 转毫秒——用
std::chrono::duration_cast<:chrono::milliseconds></:chrono::milliseconds>,否则整数截断或浮点误差会悄悄吃掉精度
跑多次取平均时,注意编译器优化和 CPU 预热
只跑一次?那结果基本没意义。但随便循环 1000 次,又可能被编译器优化掉整个被测块(尤其空循环或纯计算),或者 CPU 还没升频就结束了。
实操建议:
- 用 volatile 变量“骗过”编译器:比如把计算结果存到
volatile int dummy = result;,防止被优化剔除 - 至少预热 10–20 次再开始计时——第一次执行常有指令缓存、分支预测未生效等问题
- 总次数别硬写死,改用“持续跑够 100ms 以上”更稳:
while (total_duration - 记录每次耗时到
std::vector,最后用std::accumulate算平均,别边跑边累加——浮点误差会累积
完整可粘贴的最小示例
以下代码测 std::sort 对 10000 个随机数排序的平均耗时(毫秒,带小数):
#include <chrono>
#include <vector>
#include <algorithm>
#include <random>
#include <numeric><p>double measure_sort_avg_ms(int trials = 50) {
std::vector<int> v(10000);
std::mt19937 gen{std::random_device{}()};
std::uniform_int_distribution dist(1, 100000);</int></p>
<pre class="brush:php;toolbar:false;">// 预热
for (int i = 0; i < 10; ++i) {
for (auto& x : v) x = dist(gen);
std::sort(v.begin(), v.end());
}
std::vector<double> times;
times.reserve(trials);
for (int i = 0; i < trials; ++i) {
for (auto& x : v) x = dist(gen);
auto start = std::chrono::high_resolution_clock::now();
std::sort(v.begin(), v.end());
auto end = std::chrono::high_resolution_clock::now();
auto ms = std::chrono::duration_cast<std::chrono::nanoseconds>(end - start).count() / 1e6;
times.push_back(ms);
}
return std::accumulate(times.begin(), times.end(), 0.0) / times.size();
}
注意:这里用 nanoseconds 计数再转 double 毫秒,比直接 cast 到 milliseconds 更准——后者会向下取整丢精度。
跨平台要注意的冷知识
std::chrono::high_resolution_clock 在 Windows 上通常等价于 QueryPerformanceCounter,很稳;但在某些旧版 GCC(如 4.8)或嵌入式工具链里,它可能退化成 std::chrono::system_clock,导致结果跳变。
保险做法:
- 构建时加
static_assert:static_assert(std::chrono::high_resolution_clock::is_steady, "HR clock not steady"); - 运行时打个 quick check:连续调用两次
now(),差值若 > 100μs,说明分辨率太差,该换方案了 - 别信文档写的“最高精度”,实测才是唯一标准——同一段代码在 WSL、Docker、裸机上结果可能差 2–3 倍
真正难的从来不是写对那几行 chrono 调用,而是让被测代码不被干扰、让环境不拖后腿。测出来 0.83ms 还是 0.87ms,差的不是代码,是那一次没关掉的杀毒软件后台扫描。
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











