Google Benchmark中是否有替代Google Test TestWithParam的参数化方案?
Google Benchmark自定义多类型参数的实现方案
Google Benchmark的Args()接口确实仅支持int64_t类型参数,要实现混合类型的参数化测试,有两种成熟的兼容方案:
方案1:参数池+索引映射(全版本兼容,稳定性最高)
核心逻辑是提前把所有多类型参数组合存储到静态容器中,通过Args()传递参数对应的索引值,在测试逻辑中通过索引读取完整参数即可。
实现步骤:
- 自定义参数结构体,存储需要的所有类型的测试参数
- 提前定义静态参数池,存入所有需要测试的参数组合
- 注册基准测试时,通过
Args()传递参数对应的数组索引 - 测试逻辑/夹具初始化时,从状态参数中读取索引,从参数池获取完整参数
示例代码:
#include <benchmark/benchmark.h> #include <string> #include <vector> // 1. 自定义参数结构体 struct CustomParam { std::string img_path; int width_scale; int height_scale; }; // 2. 静态参数池,存储所有测试参数组合 static const std::vector<CustomParam> g_test_params = { {"1.jpg", 2, 2}, {"2.jpg", 3, 3} }; // 原有测试夹具调整 class AreaResizeFast_Fixture : public benchmark::Fixture { public: void SetUp(const ::benchmark::State& state) override { // 3. 读取索引,获取对应完整参数 int param_idx = state.range(0); current_param = g_test_params[param_idx]; // 其他初始化逻辑,比如根据路径读取图片等 } CustomParam current_param; }; BENCHMARK_DEFINE_F(AreaResizeFast_Fixture, cv)(benchmark::State& state) { for (auto _ : state) { // 直接使用current_param的参数即可 resize_func(current_param.img_path, current_param.width_scale, current_param.height_scale); } } // 4. 注册时传递参数索引 BENCHMARK_REGISTER_F(AreaResizeFast_Fixture, cv) ->Unit(benchmark::kMillisecond) ->UseRealTime() ->Arg(0) // 对应第一个参数组合 ->Arg(1) // 对应第二个参数组合 ->ArgName("param_index");
如果需要测试报告里直接显示具体参数而不是索引,可以在SetUp中调用state.SetLabel()设置自定义标签,或者通过benchmark::AddCustomContext追加参数说明。
方案2:BENCHMARK_CAPTURE捕获参数(v1.5.0及以上版本支持)
如果使用的Google Benchmark版本足够新,可以直接用BENCHMARK_CAPTURE宏直接捕获自定义参数,不需要维护参数池和索引,代码更简洁。
示例代码:
#include <benchmark/benchmark.h> #include <string> void BM_AreaResizeCV(benchmark::State& state, const std::string& img_path, int w_scale, int h_scale) { for (auto _ : state) { resize_func(img_path, w_scale, h_scale); } } // 直接捕获每个参数组合注册 BENCHMARK_CAPTURE(BM_AreaResizeCV, 1jpg_2x2, "1.jpg", 2, 2) ->Unit(benchmark::kMillisecond) ->UseRealTime(); BENCHMARK_CAPTURE(BM_AreaResizeCV, 2jpg_3x3, "2.jpg", 3, 3) ->Unit(benchmark::kMillisecond) ->UseRealTime();
搭配夹具使用时,只需要给夹具构造函数添加自定义参数,再用BENCHMARK_CAPTURE注册夹具实例即可。
内容的提问来源于stack exchange,提问作者ChrisZZ
相关产品推荐
相关产品推荐

