C++性能测试工具:google benchmark入门

如果你正在寻找一款c++性能测试工具,那么这篇文章是不容错过的。

市面上的benchmark工具或多或少存在一些使用上的不便,那么是否存在一个使用简便又功能强大的性能测试工具呢?答案是google/benchmark。

google/benchmark是一个由Google开发的基于googletest框架的c++ benchmark工具,它易于安装和使用,并提供了全面的性能测试接口。

下面我将介绍google/benchmark的安装并用一个简短的例子介绍它的简单使用。

安装google/benchmark

google/benchmark基于c++11标准和googletest框架,所以安装前需要先做一些准备工作。

首先是安装g++和cmake。

Debian/Ubuntu:

sudo apt install g++ cmake

Arch Linux/Manjaro Linux:

sudo pacman -s g++ cmake

确保你的g++版本在5.0以上,否则可能不能很好地支持c++11的某些特性。

小编是一个有着6年工作经验的工程师,关于C++,编程,自己有做材料的整合,一个完整的C++编程学习路线,学习资料和工具,能够进我的群7253,-91790收取,免费送给大家,希望你也能凭着自己的努力,成为下一个优秀的程序员

然后是googletest框架,你可以选择单独安装,不过这里我选择将其作为benchmark源码树的依赖而不单独安装它,因为benchmark在编译安装时需要googletest但是在使用时并不需要,为了篇幅我们选择后者。

准备工作完成后选择一个合适的目录,然后运行下面的命令:

git clone https://github.com/google/benchmark.git

git clone https://github.com/google/googletest.git benchmark/googletest

mkdir build && cd build

cmake -DCMAKE_BUILD_TYPE=RELEASE ../benchmark

make -j4

# 如果想全局安装就接着运行下面的命令

sudo make install

头文件会被安装至/usr/local/include,库文件会安装至/usr/local/lib。

现在安装完成了,我们来看看benchmark如何使用。

google/benchmark的简单使用

我们的例子将会对比三种访问std::array容器内元素方法的性能,进而演示benchmark的使用方法。

先看代码:

#include <benchmark/benchmark.h>

#include <array>

constexpr int len = 6;

// constexpr function具有inline属性,你应该把它放在头文件中

constexpr auto my_pow(const int i)

{

return i * i;

}

// 使用operator[]读取元素,依次存入1-6的平方

static void bench_array_operator(benchmark::State& state)

{

std::array<int, len> arr;

constexpr int i = 1;

for (auto _: state) {

arr[0] = my_pow(i);

arr[1] = my_pow(i+1);

arr[2] = my_pow(i+2);

arr[3] = my_pow(i+3);

arr[4] = my_pow(i+4);

arr[5] = my_pow(i+5);

}

}

BENCHMARK(bench_array_operator);

// 使用at()读取元素,依次存入1-6的平方

static void bench_array_at(benchmark::State& state)

{

std::array<int, len> arr;

constexpr int i = 1;

for (auto _: state) {

arr.at(0) = my_pow(i);

arr.at(1) = my_pow(i+1);

arr.at(2) = my_pow(i+2);

arr.at(3) = my_pow(i+3);

arr.at(4) = my_pow(i+4);

arr.at(5) = my_pow(i+5);

}

}

BENCHMARK(bench_array_at);

// std::get<>(array)是一个constexpr function,它会返回容器内元素的引用,并在编译期检查数组的索引是否正确

static void bench_array_get(benchmark::State& state)

{

std::array<int, len> arr;

constexpr int i = 1;

for (auto _: state) {

std::get<0>(arr) = my_pow(i);

std::get<1>(arr) = my_pow(i+1);

std::get<2>(arr) = my_pow(i+2);

std::get<3>(arr) = my_pow(i+3);

std::get<4>(arr) = my_pow(i+4);

std::get<5>(arr) = my_pow(i+5);

}

}

BENCHMARK(bench_array_get);

BENCHMARK_MAIN();

我们可以看到每一个benchmark测试用例都是一个类型为std::function<void(benchmark::State&)>的函数,其中benchmark::State&负责测试的运行及额外参数的传递。

随后我们使用for (auto _: state) {}来运行需要测试的内容,state会选择合适的次数来运行循环,时间的计算从循环内的语句开始,所以我们可以选择像例子中一样在for循环之外初始化测试环境,然后在循环体内编写需要测试的代码。

测试用例编写完成后我们需要使用BENCHMARK(<function_name>);将我们的测试用例注册进benchmark,这样程序运行时才会执行我们的测试。

最后是用BENCHMARK_MAIN();替代直接编写的main函数,它会处理命令行参数并运行所有注册过的测试用例生成测试结果。

示例中大量使用了constexpt,这是为了能在编译期计算出需要的数值避免对测试产生太多噪音。

然后我们编译测试程序:

g++ -Wall -std=c++14 -pthread -lbenchmark benchmark_example.cpp

benchmark需要链接libbenchmark.so,所以需要指定-lbenchmark,此外还需要thread的支持,因为libstdc++不提供thread的底层实现,我们需要pthread。另外不建议使用-lpthread,官方表示会出现兼容问题,在我这测试也会出现链接错误。

编译好程序后就可以运行测试了:

显示的警告信息表示在当前系统环境有一些噪音(例如其他在运行的程序)可能导致结果不太准确,并不影响我们的测试。

测试结果与预期基本相符,std::get最快,at()最慢。

以上就是google/benchmark的安装和简单使用,

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,864评论 6 494
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,175评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,401评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,170评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,276评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,364评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,401评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,179评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,604评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,902评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,070评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,751评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,380评论 3 319
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,077评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,312评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,924评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,957评论 2 351

推荐阅读更多精彩内容