[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

相关文章

Golang操作DuckDB实战案例分享

《Golang操作DuckDB实战案例分享》DuckDB是一个嵌入式SQL数据库引擎,它与众所周知的SQLite非常相似,但它是为olap风格的工作负载设计的,DuckDB支持各种数据类型和SQL特性... 目录DuckDB的主要优点环境准备初始化表和数据查询单行或多行错误处理和事务完整代码最后总结Duck

Golang的CSP模型简介(最新推荐)

《Golang的CSP模型简介(最新推荐)》Golang采用了CSP(CommunicatingSequentialProcesses,通信顺序进程)并发模型,通过goroutine和channe... 目录前言一、介绍1. 什么是 CSP 模型2. Goroutine3. Channel4. Channe

C#使用yield关键字实现提升迭代性能与效率

《C#使用yield关键字实现提升迭代性能与效率》yield关键字在C#中简化了数据迭代的方式,实现了按需生成数据,自动维护迭代状态,本文主要来聊聊如何使用yield关键字实现提升迭代性能与效率,感兴... 目录前言传统迭代和yield迭代方式对比yield延迟加载按需获取数据yield break显式示迭

Java实现任务管理器性能网络监控数据的方法详解

《Java实现任务管理器性能网络监控数据的方法详解》在现代操作系统中,任务管理器是一个非常重要的工具,用于监控和管理计算机的运行状态,包括CPU使用率、内存占用等,对于开发者和系统管理员来说,了解这些... 目录引言一、背景知识二、准备工作1. Maven依赖2. Gradle依赖三、代码实现四、代码详解五

Golang使用minio替代文件系统的实战教程

《Golang使用minio替代文件系统的实战教程》本文讨论项目开发中直接文件系统的限制或不足,接着介绍Minio对象存储的优势,同时给出Golang的实际示例代码,包括初始化客户端、读取minio对... 目录文件系统 vs Minio文件系统不足:对象存储:miniogolang连接Minio配置Min

Golang使用etcd构建分布式锁的示例分享

《Golang使用etcd构建分布式锁的示例分享》在本教程中,我们将学习如何使用Go和etcd构建分布式锁系统,分布式锁系统对于管理对分布式系统中共享资源的并发访问至关重要,它有助于维护一致性,防止竞... 目录引言环境准备新建Go项目实现加锁和解锁功能测试分布式锁重构实现失败重试总结引言我们将使用Go作

如何测试计算机的内存是否存在问题? 判断电脑内存故障的多种方法

《如何测试计算机的内存是否存在问题?判断电脑内存故障的多种方法》内存是电脑中非常重要的组件之一,如果内存出现故障,可能会导致电脑出现各种问题,如蓝屏、死机、程序崩溃等,如何判断内存是否出现故障呢?下... 如果你的电脑是崩溃、冻结还是不稳定,那么它的内存可能有问题。要进行检查,你可以使用Windows 11

正则表达式高级应用与性能优化记录

《正则表达式高级应用与性能优化记录》本文介绍了正则表达式的高级应用和性能优化技巧,包括文本拆分、合并、XML/HTML解析、数据分析、以及性能优化方法,通过这些技巧,可以更高效地利用正则表达式进行复杂... 目录第6章:正则表达式的高级应用6.1 模式匹配与文本处理6.1.1 文本拆分6.1.2 文本合并6

Vue3 的 shallowRef 和 shallowReactive:优化性能

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

性能测试介绍

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