c++性能测试⼯具:googlebenchmark⼊门(⼀)
如果你正在寻⼀款c++性能测试⼯具,那么这篇⽂章是不容错过的。
市⾯上的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的某些特性。
然后是googletest框架,你可以选择单独安装,不过这⾥我选择将其作为benchmark源码树的依赖⽽不单独安装它,因为benchmark在编译安装时需要googletest但是在使⽤时并不需要,为了篇幅我们选择后者。
准备⼯作完成后选择⼀个合适的⽬录,然后运⾏下⾯的命令:
git clone github/google/benchmark.git
git clone github/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);
ubuntu使用入门教程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 benchmark_example.cpp -pthread -lbenchmark
benchmark需要链接libbenchmark.so,所以需要指定-lbenchmark,此外还需要thread的⽀持,因为libstdc++不提供thread的底层实现,我们需要pthread。另外不建议使⽤-lpthread,官⽅表⽰会出现兼容问题,在我这测试也会出现链接错误。注意⽂件名⼀定要在-lbenchmark前⾯,否则编译会失败,具体参见:
如果你是在Windows平台使⽤google/benchmark,那么你需要额外链接shlwapi.lib才能使benchmark正常编译和运⾏。详细信息在。
编译好程序后就可以运⾏测试了:
显⽰的警告信息表⽰在当前系统环境有⼀些噪⾳(例如其他在运⾏的程序)可能导致结果不太准确,并不影响我们的测试。
在Windows上通常没有上述警告,如果你需要在Linux平台上去除相关警告的话,请参考。
测试结果与预期基本相符,std::get最快,at()最慢。
以上就是google/benchmark的安装和简单使⽤,中我会介绍更多使⽤benchmark的技巧,如有错误欢迎指正。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论