C++ 之Google benchmark测试与分析

news2024/11/27 15:50:43

0. 简介

作为一个程序而言,benchmark是非常关键的一个衡量指标,无论是程序算法的指标还是程序运行性能的指标,这些我们都可以去完成衡量。对于性能衡量而言google benchmark无疑是一个比较好的选择

1. google benchmark安装

1.1 下载地址

https://github.com/google/benchmark

1.2 编译安装

登录 linux环境,执行以下命令,进行编译安装:

git clone https://github.com/google/benchmark.git
cd benchmark
git clone https://github.com/google/googletest.git
mkdir build
cd build
cmake .. -DCMAKE_BUILD_TYPE=RELEASE
make
sudo make install

2. 代码编写

创建一个C++源文件,并编写包含基准测试函数的代码。例如,创建一个名为benchmark_example.cpp的文件,并编写如下内容:

#include <benchmark/benchmark.h>

static void BM_MyFunction(benchmark::State& state) {
    // 在这里编写您要测试的代码
    for (auto _ : state) {
        // 执行您的代码
    }
}

BENCHMARK(BM_MyFunction);

BENCHMARK_MAIN();

在上述示例中,BM_MyFunction是您要测试的函数。

然后我们可以使用C++编译器编译您的代码,并链接Google Benchmark库。

g++ benchmark_example.cpp -o benchmark_example -lbenchmark -lpthread

如果是cmakelist,则可以使用

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
# benchmark依赖thread线程库
add_library(benchmark STATIC IMPORTED)
set_property(TARGET benchmark PROPERTY IMPORTED_LOCATION /usr/local/lib/libbenchmark.a)

add_executable(demo demo.cpp)
target_link_libraries(demo
    benchmark
)

install(TARGETS
    demo
    DESTINATION "bin/"
)

2.1 基础代码调用测试

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

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

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

#include <benchmark/benchmark.h>
#include <vector>
#include <array>

constexpr int len = 6;
std::vector<int> vec{1, 2, 3, 4, 5, 6};
std::array<int, len> array{1, 2, 3, 4, 5, 6};

// benchmark::State &state用于维护测试上下文信息,以及控制迭代次数
static void vector_test(benchmark::State &state)
{
    for (auto _ : state)
    {
        vec[0];
        vec[1];
        vec[2];
        vec[3];
        vec[4];
        vec[5];
    }
}

static void array_test(benchmark::State &state)
{
    for (auto _ : state)
    {
        array[0];
        array[1];
        array[2];
        array[3];
        array[4];
        array[5];
    }
}

// 注册测试用例
BENCHMARK(vector_test);
BENCHMARK(array_test);
// benchmark的主函数
BENCHMARK_MAIN();

结果格式如下:

Load Average: 0.43, 0.25, 0.10
------------------------------------------------------
Benchmark            Time             CPU   Iterations
------------------------------------------------------
vector_test       6.81 ns         6.81 ns    102373755
array_test        13.6 ns         13.6 ns     51227934

2.2 传参调用测试

上面的测试用例都只接受一个benchmark::State&类型的参数,所以我们可以使用BENCHMARK宏生成的对象的Arg方法来完成参数的传递。


传递进来的参数会被放入state对象内部存储,通过range方法获取,调用时的参数0是传入参数的需要,对应第一个参数

#include <benchmark/benchmark.h>
#include <vector>
#include <array>

static void bench_array_ring_insert_int(benchmark::State& state)
{
    auto length = state.range(0);
    auto ring = ArrayRing<int>(length);
    for (auto _: state) {
        for (int i = 1; i <= length; ++i) {
            ring.insert(i);
        }
        state.PauseTiming();
        ring.clear();
        state.ResumeTiming();
    }
}
// 下面我们生成测试插入10次的测试用例
BENCHMARK(bench_array_ring_insert_int)->Arg(10);

static void bench_array_ring_insert_int(benchmark::State& state)
{
    auto ring = ArrayRing<int>(state.range(0));
    for (auto _: state) {
        for (int i = 1; i <= state.range(1); ++i) {
            ring.insert(i);
        }
        state.PauseTiming();
        ring.clear();
        state.ResumeTiming();
    }
}
BENCHMARK(bench_array_ring_insert_int)->Args({10, 10});

// benchmark的主函数
BENCHMARK_MAIN();

2.3 模板类的调用测试

如果针对每一种情况写测试函数,显然违反了DRY原则,因为除了vector的类型参数不同,其他代码几乎是完全一样的。

#include <benchmark/benchmark.h>
#include <vector>
#include <array>

template <typename T, std::size_t length, bool is_reserve = true>
void bench_vector_reserve(benchmark::State& state)
{
	for (auto _ : state) {
		std::vector<T> container;
		if constexpr (is_reserve) {
			container.reserve(length);
		}
		for (std::size_t i = 0; i < length; ++i) {
			container.push_back(T{});
		}
	}
}

BENCHMARK_TEMPLATE(bench_vector_reserve, std::string, 100);
// benchmark的主函数
BENCHMARK_MAIN();

3. 使用Benchmark接口

…详情请参照古月居

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1166826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

矢量图形设计软件:Illustrator 2024(AI)中文激活版

Illustrator 2024是一款强大的矢量图形设计软件&#xff0c;它具备丰富的绘图和设计工具&#xff0c;用户可以通过画笔、铅笔、形状、路径等工具创建各种矢量图形和插图设计。新版本还增强了智能功能&#xff0c;可以自动从图像或调色板中提取颜色并应用到设计中&#xff0c;同…

云工作流 CloudFlow 重磅发布,流程式开发让云上应用构建更简单

为了让企业和开发者更快速、便捷地进行云上开发&#xff0c;阿里云重磅发布云工作流&#xff08;CloudFlow&#xff09;&#xff0c;它是一款强大的面向开发者的流程编排开发工具&#xff0c;全托管、高并发、高可用&#xff0c;帮助用户简化和自动化复杂的云上业务流程和工作流…

数据结构 - ArrayList - 动态修改的数组

目录 实现一个通用的顺序表 总结 包装类 装箱 / 装包 和 拆箱 / 拆包 ArrayList 与 顺序表 ArrayList基础功能演示 add 和 addAll &#xff0c;添加元素功能 ArrayList的扩容机制 来看一下&#xff0c;下面的代码是否存在缺陷 模拟实现 ArrayList add 功能 add ind…

Linux安装配置awscli命令行接口工具及其从aws上传下载数据

官网技术文档有全面介绍&#xff1a;安装或更新 AWS CLI 的最新版本 - AWS Command Line Interface在系统上安装 AWS CLI。https://docs.aws.amazon.com/zh_cn/cli/latest/userguide/getting-started-install.html#getting-started-install-instructionsawscli常用命令参考&…

红海云签约澳森集团,为钢铁行业人力资源数字化转型注入新动能

辛集市澳森特钢集团有限公司&#xff08;以下简称“澳森集团”&#xff09;是集钢铁冶炼、轧钢及钢材深加工、新型建材、国际贸易、房地产开发、酒店餐饮、热力供应于一体的大型钢铁联合企业&#xff0c;是华北地区最具品牌影响力和核心竞争力的综合性大型企业集团。 近日&…

LBS营销|基于位置信息的营销策略

LBS营销&#xff08;Location-Based Services Marketing&#xff09;是一种基于位置信息的营销策略&#xff0c;它利用移动设备和位置数据来为消费者提供与其当前位置相关的个性化信息和服务。LBS营销通过分析用户的地理位置&#xff0c;向他们提供特定地点或地理区域的有关信息…

虚拟数字人技术篇

1. 虚拟数字人概念解析 虚拟数字人它是由三个部分组成:虚拟、数字、人。 虚拟:存在于非物理世界,多模态存在于各种介质;数字:数字化,可复制多个分身,多技术综合体;人:具备拟人化的外表和行为交互的能力。具体说明如下: 虚拟: 通常是指它是存在于非物理世界,可以是…

基于生成对抗网络的照片上色动态算法设计与实现 - 深度学习 opencv python 计算机竞赛

文章目录 1 前言1 课题背景2 GAN(生成对抗网络)2.1 简介2.2 基本原理 3 DeOldify 框架4 First Order Motion Model5 最后 1 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 基于生成对抗网络的照片上色动态算法设计与实现 该项目较为新颖&am…

Docker安装matomo

Docker安装matomo 文章目录 Docker安装matomo1.安装Docker2.matomo安装 1.安装Docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun2.matomo安装 #拉取matomo镜像 docker pull matomo#启动matomo容器 docker run -d --name matomo -p 8093:80 -v /do…

喜讯!苏州箱讯获评苏州市软件和信息服务业 “头雁”培育企业

近日&#xff0c;由中国电子信息产业发展研究院、中国工业经济联合会、国家智能制造专家委员会、国家产业基础专家委员会、江苏省工业和信息化厅、江苏省国有资产监督管理委员会、苏州市人民政府共同主办的2023第三届中控中国大会在苏州太湖国际会议中心举办。 本届大会以“生态…

erp 技术的发展趋势和方向有哪些?

近日&#xff0c;亿欧智库重磅发布了《2022中国制造业ERP研究报告》。亿欧通过桌面研究及行业专家访谈&#xff0c;对ERP在制造业领域的应用情况进行分析&#xff0c;洞察ERP针对制造业不同场景的服务模式&#xff0c;研讨制造业ERP的未来发展趋势&#xff0c;旨在帮助制造业企…

OPCUA 行业配套标准:机器人

OPC UA 定义了对象&#xff0c;对象类型&#xff0c;结构化组织能力和定义对象之间关系的能力&#xff0c;利用这些基础和衍生类型及对象&#xff0c;用户还可以搭建出更复杂的类型&#xff0c;关系和对象。 如果不同的厂商或者用户定义的信息模型不同&#xff0c;将会影响系统…

springboot+vue基于JAVA的企业内部人员绩效量化管理系统的设计与实现【内含源码+文档+部署教程】

博主介绍&#xff1a;✌全网粉丝10W,前互联网大厂软件研发、集结硕博英豪成立工作室。专注于计算机相关专业毕业设计项目实战6年之久&#xff0c;选择我们就是选择放心、选择安心毕业✌ &#x1f345;由于篇幅限制&#xff0c;想要获取完整文章或者源码&#xff0c;或者代做&am…

时间复杂度的计算技巧-算法模型中的时间复杂度如何计算,有哪些技巧呢

大家好&#xff0c;我是微学AI&#xff0c;今天给大家介绍一下时间复杂度的计算技巧-算法模型中的时间复杂度如何计算&#xff0c;有哪些技巧呢&#xff0c;算法的时间复杂度是评估算法性能和效率的一种方式&#xff0c;它表示算法需要执行多少次基本操作才能完成其任务&#x…

【数据库】关系数据库管理系统 (RDBMS) 中事务处理的四个特性ACID

给自己一个目标&#xff0c;然后坚持一段时间&#xff0c;总会有收获和感悟&#xff01; 数据库事务是指一组数据库操作&#xff08;例如插入、更新、删除等&#xff09;&#xff0c;被视为一个单独的逻辑操作单元&#xff0c;并且要么全部执行成功&#xff0c;要么全部不执行&…

Eolink Apikit 如何对所有 API 异常请求实时监控 ?

API 监控适合业务在互联网上&#xff0c;并且用户来自多个不同的地区&#xff0c;且对API的要求较高的场合&#xff0c;用于解决以下的问题&#xff1a; 发现由于网络中断或者是API响应异常等导致的服务不可用 及时对异常的API进行告警 记录监控的日志&#xff0c;方便排查 …

基于Jaccard相似度的推荐算法---示例

目录 数据展示推荐算法的分类基于相似度基于流行度/上下文/社交网络 Jaccard相似度分析数据的特点可以考虑的方法计算方法优缺点计算用户之间的Jaccard相似度获取与给定最相似的10个用户对1713353的用户推荐10本书 数据展示 import pandas as pd import numpy as np# 读取CSV文…

vue+elementUI 设置el-descriptions固定长度并对齐

问题描述 对于elementUI组件&#xff0c;el-descriptions 在以类似列表的形式排列的时候&#xff0c;上下无法对齐的问题。 问题解决 在el-descriptions 标签中&#xff0c;添加属性&#xff1a; :contentStyle"content_style" 控制其内容栏长度 <el-descripti…

Visual Components Robotics OLP解决方案 北京衡祖

Visual Components 引入了“Visual Components Robotics OLP”的重大升级&#xff0c;合并了制造模拟和机器人离线编程。该解决方案利用 Delfoi Robotics 的技术&#xff0c;提高生产率、减少停机时间并减少浪费。 一、探索下一代离线机器人编程软件 自 1999 年以来&#xff0…

强大的pdf编辑软件:Acrobat Pro DC 2023中文

Acrobat Pro DC 2023是一款强大的PDF编辑和管理软件&#xff0c;它提供了广泛的功能&#xff0c;使用户能够轻松创建、编辑、转换和共享PDF文档。通过直观的界面和先进的工具&#xff0c;用户可以快速进行文本编辑、图像调整、页面管理等操作&#xff0c;同时支持OCR技术&#…