[Golang]Benchmark性能测试

2024-08-30 10:18
文章标签 golang 性能 测试 benchmark

本文主要是介绍[Golang]Benchmark性能测试,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

前言

基准测试是测量一个程序在固定工作负载下的性能,Go语言也提供了可以支持基准性能测试的benchmark

使用方法

下面展示一个基准测试的示例代码来剖析下它的使用方式:

func Benchmark_test(b *testing.B) {for i := 0; i < b.N ; i++ {s := make([]int, 0)for i := 0; i < 10000; i++ {s = append(s, i)}}
}
  • 进行基准测试的文件必须以*_test.go的文件为结尾,这个和测试文件的名称后缀是一样的,例如abc_test.go
  • 参与Benchmark基准性能测试的方法必须以Benchmark为前缀,例如BenchmarkABC()
  • 参与基准测试函数必须接受一个指向Benchmark类型的指针作为唯一参数,*testing.B
  • 基准测试函数不能有返回值
  • b.ResetTimer是重置计时器,调用时表示重新开始计时,可以忽略测试函数中的一些准备工作
  • b.N是基准测试框架提供的,表示循环的次数,因为需要反复调用测试的代码,才可以评估性能

命令及参数

性能测试命令为go test [参数],比如go test -bench=. -benchmem,具体的命令参数及含义如下:

参数含义
-bench regexp性能测试,支持表达式对测试函数进行筛选。
-bench. 则是对所有的benchmark函数测试,指定名称则只执行具体测试方法而不是全部
-benchmem性能测试的时候显示测试函数的内存分配的统计信息
-count n运行测试和性能多少此,默认一次
-run regexp只运行特定的测试函数, 比如-run ABC只测试函数名中包含ABC的测试函数
-timeout t测试时间如果超过t, panic,默认10分钟
-v显示测试的详细信息,也会把Log、Logf方法的日志显示出来

测试结果

执行命令后,性能测试的结果展示如下

$ go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: program/benchmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Benchmark_test-12        7439091               152.0 ns/op           248 B/op          5 allocs/op
PASS
ok      promgram/benchmark    1.304s

对以上结果进行逐一分析:

结果项含义
Benchmark_test-12Benchmark_test 是测试的函数名
-12 表示GOMAXPROCS(线程数)的值为12
7439091表示一共执行了7439091次,即b.N的值
152.0 ns/op表示平均每次操作花费了152.0纳秒
248B/op表示每次操作申请了248Byte的内存申请
5 allocs/op表示每次操作申请了5次内存

性能对比实例

下面通过一个数字转换字符串的实例来对比性能测试效果,并进行分析。

//Sprintf
func BenchmarkSprintf(b *testing.B) {num := 10b.ResetTimer()for i := 0; i < b.N; i++ {fmt.Sprintf("%d", num)}
}//Format
func BenchmarkFormat(b *testing.B) {num := int64(10)b.ResetTimer()for i := 0; i < b.N; i++ {strconv.FormatInt(num, 10)}
}//Itoa
func BenchmarkItoa(b *testing.B) {num := 10b.ResetTimer()for i := 0; i < b.N; i++ {strconv.Itoa(num)}
}

下面执行命令go test -bench=. -benchmem,收到测试报告如下:

%  go test -bench=. -benchmem
goos: darwin
goarch: amd64
pkg: program/benchmark
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkSprintf-12     16364854                63.70 ns/op            2 B/op          1 allocs/op
BenchmarkFormat-12      493325650                2.380 ns/op           0 B/op          0 allocs/op
BenchmarkItoa-12        481683436                2.503 ns/op           0 B/op          0 allocs/op
PASS
ok      program/benchmark    4.007s

可以发现,BenchmarkSprintf方法耗时最长,BenchmarkFormat最快,BenchmarkItoa也很快。差别在于fmt.Sprintf()执行过程中进行了一次内存分配1 allocs/op

结合pprof分析

参数含义命令示例
-cpuprofile [file]输出cpu性能文件 go test -bench=. -benchmem -cpuprofile=cpu.out
-memprofile [file]输出mem内存性能文件 go test -bench=. -benchmem -memprofile=cpu.out

生成的CPU、内存文件可以通过go tool pprof [file]进行查看,然后在pprof中通过list [file]方法查看CPU、内存的耗时情况

### 内存情况
(pprof) list BenchmarkArrayAppend
Total: 36.49GB
ROUTINE ======================== program/benchmark.BenchmarkArrayAppend in /Users/guanjian/workspace/go/program/benchmark/benchmark_test.go11.98GB    11.98GB (flat, cum) 32.83% of Total.          .      7://Array.          .      8:func BenchmarkArrayAppend(b *testing.B) {.          .      9:   for i := 0; i < b.N; i++ {.          .     10:           var arr []int.          .     11:           for i := 0; i < 10000; i++ {11.98GB    11.98GB     12:                   arr = append(arr, i).          .     13:           }.          .     14:   }.          .     15:}
## CPU情况
(pprof) list BenchmarkArrayAppend
Total: 8.86s
ROUTINE ======================== program/benchmark.BenchmarkArrayAppend in /Users/guanjian/workspace/go/program/benchmark/benchmark_test.go10ms      640ms (flat, cum)  7.22% of Total.          .      6:.          .      7://Array.          .      8:func BenchmarkArrayAppend(b *testing.B) {.          .      9:   for i := 0; i < b.N; i++ {.          .     10:           var arr []int10ms       10ms     11:           for i := 0; i < 10000; i++ {.      630ms     12:                   arr = append(arr, i).          .     13:           }.          .     14:   }.          .     15:}

总结

go提供了benchmark性能测试的工具,提供了对函数使用内存、CPU等情况的报告分析,还可以借助pprof获得更好的分析报告等,如果想要深入分析,还可以使用之前介绍的gdb进行底层代码的链路跟踪,以及对代码进行反编译查看具体的性能损耗情况。

参考

go benchmark 性能测试 单元测试 基准测试 使用方法详解
go benchmark 性能测试

这篇关于[Golang]Benchmark性能测试的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1120540

相关文章

Vue3 的 shallowRef 和 shallowReactive:优化性能

大家对 Vue3 的 ref 和 reactive 都很熟悉,那么对 shallowRef 和 shallowReactive 是否了解呢? 在编程和数据结构中,“shallow”(浅层)通常指对数据结构的最外层进行操作,而不递归地处理其内部或嵌套的数据。这种处理方式关注的是数据结构的第一层属性或元素,而忽略更深层次的嵌套内容。 1. 浅层与深层的对比 1.1 浅层(Shallow) 定义

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

性能分析之MySQL索引实战案例

文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

黑神话,XSKY 星飞全闪单卷性能突破310万

当下,云计算仍然是企业主要的基础架构,随着关键业务的逐步虚拟化和云化,对于块存储的性能要求也日益提高。企业对于低延迟、高稳定性的存储解决方案的需求日益迫切。为了满足这些日益增长的 IO 密集型应用场景,众多云服务提供商正在不断推陈出新,推出具有更低时延和更高 IOPS 性能的云硬盘产品。 8 月 22 日 2024 DTCC 大会上(第十五届中国数据库技术大会),XSKY星辰天合正式公布了基于星

uva 10916 Factstone Benchmark(打表)

题意是求 k ! <= 2 ^ n ,的最小k。 由于n比较大,大到 2 ^ 20 次方,所以 2 ^ 2 ^ 20比较难算,所以做一些基础的数学变换。 对不等式两边同时取log2,得: log2(k ! ) <=  log2(2 ^ n)= n,即:log2(1) + log2(2) + log2 (3) + log2(4) + ... + log2(k) <= n ,其中 n 为 2 ^

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测

论文翻译:arxiv-2024 Benchmark Data Contamination of Large Language Models: A Survey

Benchmark Data Contamination of Large Language Models: A Survey https://arxiv.org/abs/2406.04244 大规模语言模型的基准数据污染:一项综述 文章目录 大规模语言模型的基准数据污染:一项综述摘要1 引言 摘要 大规模语言模型(LLMs),如GPT-4、Claude-3和Gemini的快

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动