c++oding="utf-8" ?>
根本原因是未链接 benchmark 库或 -lpthread,或链接顺序错误;cmake 中需 find_package(benchmark required) 在 add_executable 前,手动编译须 -lbenchmark -lpthread(macos 加 -ldl),且 -lbenchmark 在前。

链接失败:undefined reference 到 benchmark::Initialize 怎么办
根本原因是没链接 benchmark 库,或漏了 -lpthread(Linux/macOS 必须),或链接顺序错。CMake 是最稳的解法,手动 g++ 容易翻车。
-
find_package(benchmark REQUIRED)必须在add_executable之前,且确保 CMake 能找到它(比如用FetchContent或系统安装路径) - 手动编译时,
-lbenchmark和-lpthread缺一不可,且-lbenchmark必须在-lpthread前面;macOS 还要加-ldl - 如果用
add_subdirectory(benchmark),必须在add_executable前调用benchmark_enable_testing(),否则BENCHMARK宏可能不生效 - Clang 用户注意:旧版 libc++ 和
std::chrono交互有 bug,建议用 libstdc++ 或升级 Clang
BENCHMARK 宏里写什么才测得准
你测的不是“函数本身”,而是整个循环体。初始化、IO、构造对象这些开销全算进去了——除非你主动剥离。
- 所有耗时操作必须放在
for (auto _ : state)循环体内,不能提前提前构造对象(比如 vector、map) - 想测不同规模?用
BENCHMARK(BM_Foo)->Range(1, 1,然后在函数里读 <code>state.range(0),别硬编码 - 避免
std::cout、文件 IO、随机数生成器——它们禁用 stdout/stderr,且严重干扰计时精度 - 副作用函数(如修改全局变量)必须每次迭代前重置状态,否则后几次跑的是脏数据
- 用
benchmark::DoNotOptimize(result)防止编译器优化掉计算,但对纯函数还不够,必要时加benchmark::ClobberMemory()
为什么 RunSpecifiedBenchmarks 不输出结果
大概率是 benchmark::Initialize(&argc, &argv) 没调,或者调得太晚——它必须在任何 BENCHMARK 定义之后、RunSpecifiedBenchmarks() 之前,且必须传入 argc 和 argv 的地址。
- 推荐直接用
BENCHMARK_MAIN(),它自动处理初始化和参数解析,省去手写 main 的麻烦 - 想只跑某个测试?启动时加
--benchmark_filter=BM_MyFunc,名字必须和宏定义完全一致(区分大小写) - 默认输出是 console 表格,需要结构化数据就加
--benchmark_format=json;但 JSON 不含 CPU counter(如 cache miss),要这些得额外配置 - 短函数容易因计时抖动失真,建议加
--benchmark_min_time=1(单位秒),比默认 0.5 秒更稳
Release 模式下结果还飘,怎么办
不是代码问题,是环境干扰。Google Benchmark 的统计模型依赖稳定时钟,而 CPU 频率缩放、后台进程、虚拟机调度都会让它失效。
- Linux 下关掉频率缩放:
echo performance | sudo tee /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor - 避免在 Docker 或 VM 里跑基准测试,物理机更可靠
- 别用
std::chrono手动套在state循环里——这破坏了 Benchmark 的自适应采样和离群值剔除逻辑 - 确认构建用了
-O3,但不要加-DNDEBUG以外的宏(比如日志、断言),否则测试环境和生产不一致
C++免费学习笔记(深入):立即使用
在学习笔记中,你将探索 C++ 的入门与实战技巧!











