【Go】性能分析之benchmark基准测试
简介
benchmark
基准测试是一种测试代码性能的方法,同时也可以用来判断某段代码的CPU或者内存效率问题。很多开发都是通过benchmark
测试的结果来衡量一个函数或者功能的性能表现。一个优秀的程序员不仅需要写好自己的业务代码,其次测试代码的质量也是衡量的一个重要标准。一个完整的单元测试和性能测试,至少可以发现80%的bug。
以下以Go语言为案例,说说go的benchmark测试。
1 准备
- 压力测试的环境,必须同一个测试环境,修改前后才有对比可言。
- 压力测试的环境,最好和线上运行的系统相同,建议使用
linux
,有条件的可以与线上系统的配置相同。 - 机器处于闲置状态,测试时不要执行其他任务,也不要和其他人共享硬件资源。
2 benchmark测试
2.1 测试环境的搭建
Go 语言标准库内置的 testing 测试框架提供了基准测试benchmark
的能力,能让我们很容易地对某一段代码进行性能试。benchmark
的测试方式和普通的测试方式相同,创建的测试文件都需要以_test.go
结尾。一般测试的情况,都是一个源文件代码会对应一个测试文件。测试文件的量可以会远超业务代码的量。
使用命命令行操作:
|
|
- main.go
- 测试什么程序的性能呢?这个问题我想了很久。排序算法?
|
|
- 新建测试程序,编写测试代码
vim main_test.go
|
|
- benchmark 和普通的单元测试用例是使用,测试文件都是需要
_test.go
结尾命名。 - 函数名以
Benchmark
开头,参数是b *testing.B
。 func TestMain(m *testing.M)
是测试前运行的数据,这边是实现随机一组int类型的数据。
这样我们的测试环境就搭建好了,可以开始执行我们的测试了。
2.2 Go test 执行测试用例
|
|
在测试目录执行go test
,使用 go test -bench .
执行当前目录下的所有benchmark
测试单元。
如果目录下有很多的测试单元,你只想执行其中一个怎么办?
-bench
参数支持使用正则表达式,正则表达式匹配到的benchmark
测试才会执行。
$ go test -bench='^bubbleSort$' .
|
|
benchmark执行的过程中,过滤单元测试的输出
-run
匹配一个从来没有单元测试的方法,过滤单元测试的输出,可以使用以下两种的测试方法:-run=none
-run=^$
eg:
go test -bench=. -run=none
go test -bench=. -run=^$
2.3 Go test的一些扩展参数
2.3.1 准确度的提升
正确的使用扩展参数的情况,能提高单元测试精确度。
-benchtime
和-count
参数-cpu
-benchtime
测试时间
go test -bench=. -benchtime=5s .
|
|
为什么时间是 11.097s
不是 5s
,测试用例编译、执行、销毁等是需要时间的。
测试次数
go test -bench=. -benchtime=5x .
|
|
-cpu
设置cpu使用个数对程序的性能的影响。
go test -bench=. -cpu=2,4,8 .
|
|
为什么2,4,8核心的性能几乎是一样的?因为没有使用到多线程的机制,写的demo是串行的。
2.3.2 实现内存的统计
-benchmem
go test -bench=. -benchmem
|
|
3 benchmark扩展和原理分析
3.1 精确耗时处理
- ResetTimer
- 受到耗时准备任务的干扰情况,使用
ResetTimer
重置时间。
- 受到耗时准备任务的干扰情况,使用
- StopTimer 和 StartTimer
- 每次函数调用前后需要一些准备工作和清理工作,可以使用
StopTimer
暂停计时以及使用StartTimer
开始计时。
- 每次函数调用前后需要一些准备工作和清理工作,可以使用
3.2 原理简单说明
|
|
通过demo可以看到,benchmark
测试的时候,使用的参数为b *testing.B
,有一个很重要用到的数据类型为b.N
,通过for
循环可以看出,是用例需要执行的次数。b.N
对于每个用例测试可能都是不一样的。
那这个b.N的数值的N是如何决定的呢?
b.N从1开始,如果测试的用例可以在 1s 内完成,b.N
的值增加,再次的去执行。b.N的值大概是以指数的方式序列递增,越到后面,增加的越快。
demo:
|
|
测试命令
|
|
- 为什么只执行一次的话,应该就是上面的方式方法。
总结
介绍了benchmark的使用,以及相关扩展参数的使用方法。快去实践一下吧? 后续的话,介绍使用pprof进行性能的分析。