0

0

c++如何使用Google Benchmark测试性能_c++ 性能测试用例编写与分析【指南】

穿越時空

穿越時空

发布时间:2026-01-05 16:27:10

|

243人浏览过

|

来源于php中文网

原创

正确链接 Google Benchmark 需用 CMake find_package(benchmark REQUIRED) 并 target_link_libraries,或手动链接 -lbenchmark -lpthread(顺序不可颠倒);benchmark 函数须在 state 循环内重复执行核心操作,避免初始化/IO 外移;其时间统计基于多轮自适应采样与离群值剔除,非 raw clock 测量。

c++如何使用google benchmark测试性能_c++ 性能测试用例编写与分析【指南】

如何正确链接 Google Benchmark 并运行第一个测试

Google Benchmark 不是头文件库,直接 #include 后编译会报 undefined reference to `benchmark::internal::InitializeRegistry()' —— 这是最常见的卡点。必须显式链接静态库或使用 CMake 正确导入。

推荐用 CMake(v3.10+)管理:

find_package(benchmark REQUIRED)
add_executable(bench_main bench.cpp)
target_link_libraries(bench_main benchmark)

若手动编译,需确保:
- 已用 cmake -DBENCHMARK_BUILD_TESTS=OFF -DCMAKE_BUILD_TYPE=Release . && make -j 构建 benchmark 库
- 编译命令包含 -L/path/to/benchmark/build/src -lbenchmark -lpthread
- libbenchmark.a 必须在 -lpthread 之前链接,否则 macOS/Linux 下可能报 pthread 符号未定义

编写一个可复现的 benchmark 函数要注意什么

核心原则:不要在 BENCHMARK 宏里做初始化、分配、IO 或依赖外部状态。所有耗时操作必须放在 state 循环体内,且每次迭代逻辑一致。

常见错误写法:

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

GPTBots
GPTBots

企业级AI智能体构建平台

下载
static void BM_StringCreation(benchmark::State& state) {
  std::string s;  // ❌ 错误:只创建一次,后续迭代不重复
  for (auto _ : state) {
    s.clear();      // ✅ 正确:每次迭代重置
    s += "hello";
  }
}

关键点:
- state.range(0) 可传入参数(如数据规模),配合 BENCHMARK_RANGE 使用
- 用 state.PauseTiming() / state.ResumeTiming() 排除 setup/teardown 开销
- 若测试函数有副作用(如修改全局变量),需调用 state.counters["foo"] = ... 手动记录指标,避免被优化掉

为什么 run\_benchmark 输出的 “time per iteration” 和自己用 clock() 测的差很多

Google Benchmark 默认做多轮自适应采样(Repetitions + ReportAggregatesOnly),并剔除离群值;它报告的是「单次迭代平均耗时」,不是 raw wall-clock 时间。

影响结果的关键配置:
- --benchmark_repetitions=3:重复整个 benchmark 3 次,取中位数
- --benchmark_report_aggregates_only=true:只输出 aggregate(如 mean/stddev),不打印每轮原始数据
- --benchmark_min_time=0.5:每轮至少运行 0.5 秒,保证统计显著性
- --benchmark_counters_tabular=true:让自定义 counters 对齐显示

如果你看到 2.34 ns 但手测 clock()15 ns,大概率是你没关闭编译器优化(比如忘了加 -O2),或者 benchmark 函数被完全内联+常量折叠了 —— 加 benchmark::DoNotOptimize(s) 强制保活变量

如何对比两个算法在不同数据规模下的性能拐点

BENCHMARK_RANGE + 自定义 Args 构造渐进式测试集,比手写多个 BENCHMARK 更可靠:

static void BM_SortStd(benchmark::State& state) {
  for (auto _ : state) {
    std::vector v(state.range(0), 0);
    std::iota(v.begin(), v.end(), 0);
    std::random_shuffle(v.begin(), v.end());
    std::sort(v.begin(), v.end());
  }
  state.SetComplexityN(state.range(0));
}
BENCHMARK(BM_SortStd)->Range(1<<10, 1<<18)->Complexity();

这样能自动跑 1K/2K/4K…256K 数据,并在最终报告中给出 O(N log N) 拟合度。注意:
- Range(min, max) 是按 2 的幂次扩展,想用线性步进改用 RangeMultiplier(1.5)
- state.SetComplexityN() 必须在循环外调用,否则会被忽略
- 如果算法实际复杂度非标准(如 cache-sensitive),建议额外用 state.counters["L3Misses"] 接入 perf_event(Linux)做底层归因

真正难的不是写 benchmark,而是让测试不被编译器骗、不被 CPU 预测干扰、不因内存 layout 偏差掩盖真实差异。哪怕加了 DoNotOptimize,现代 CPU 的乱序执行和分支预测仍可能让微基准失真 —— 关键路径务必用 asm volatile("" ::: "rax") 插入序列化屏障,这点文档很少提。

相关专题

更多
java基础知识汇总
java基础知识汇总

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

1458

2023.10.24

全局变量怎么定义
全局变量怎么定义

本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

73

2025.09.18

python 全局变量
python 全局变量

本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

96

2025.09.18

c++中volatile关键字的作用
c++中volatile关键字的作用

本专题整合了c++中volatile关键字的相关内容,阅读专题下面的文章了解更多详细内容。

67

2025.10.23

undefined是什么
undefined是什么

undefined是代表一个值或变量不存在或未定义的状态。它可以作为默认值来判断一个变量是否已经被赋值,也可以用于设置默认参数值。尽管在不同的编程语言中,undefined可能具有不同的含义和用法,但理解undefined的概念可以帮助我们更好地理解和编写程序。本专题为大家提供undefined相关的各种文章、以及下载和课程。

4145

2023.07.31

网页undefined是什么意思
网页undefined是什么意思

网页undefined是指页面出现了未知错误的意思,提示undefined一般是在开发网站的时候定义不正确或是转换不正确,或是找不到定义才会提示undefined未定义这个错误。想了解更多的相关内容,可以阅读本专题下面的文章。

2911

2024.08.14

网页undefined啥意思
网页undefined啥意思

本专题整合了undefined相关内容,阅读下面的文章了解更多详细内容。后续继续更新。

172

2025.12.25

macOS怎么切换用户账户
macOS怎么切换用户账户

在 macOS 系统中,可通过多种方式切换用户账户。如点击苹果图标选择 “系统偏好设置”,打开 “用户与群组” 进行切换;或启用快速用户切换功能,通过菜单栏或控制中心的账户名称切换;还能使用快捷键 “Control+Command+Q” 锁定屏幕后切换。

328

2025.05.09

漫蛙2入口地址合集
漫蛙2入口地址合集

本专题整合了漫蛙2入口汇总,阅读专题下面的文章了解更多详细内容。

162

2026.01.06

热门下载

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

精品课程

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

共48课时 | 6.7万人学习

Git 教程
Git 教程

共21课时 | 2.5万人学习

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

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