go性能测试
如何编写压力测试
压力测试用来检测函数(方法)的性能,和编写单元功能测试的方法类似,此处不再赘述,但需要注意以下几点:
压力测试用例必须遵循如下格式,其中
XXX
可以是任意字母数字的组合,但是首字母不能是小写字母go test不会默认执行压力测试的函数,如果要执行压力测试需要带上参数
-bench
,语法:-bench="test_name_regex",
例如go test -bench=".*"
表示测试全部的压力测试函数在压力测试用例中,请记得在循环体内使用
testing.B.N
,以使测试可以正常的运行文件名也必须以
_test.go
结尾
下面我们新建一个压力测试文件webbench_test.go
,代码如下所示:
1 | package main |
我们执行命令go test -test.bench=".*"
,可以看到如下结果:
1 | PASS |
上面的结果显示我们没有执行任何TestXXX
的单元测试函数,显示的结果只执行了压力测试函数,第一条显示了Benchmark_Division
执行了500000000次,每次的执行平均时间是7.76纳秒,第二条显示了Benchmark_TimeConsumingFunction
执行了500000000,每次的平均执行时间是7.80纳秒。最后一条显示总共的执行时间。
我们执行命令go test -bench=".*" -count=5
,可以看到如下结果: (使用-count可以指定执行多少次)
1 | PASS |
go test -run=文件名字 -bench=bench名字 -cpuprofile=生产的cprofile文件名称 文件夹
例子:
testBenchMark
下有个popcnt
文件夹,popcnt
中有文件popcunt_test.go
1 | ➜ testBenchMark ls popcnt |
popcunt_test.go
的问价内容:
1 | package main |
然后运行go test -bench=".*" -cpuprofile=cpu.profile ./popcnt
1 | ➜ testBenchMark go test -bench=".*" -cpuprofile=cpu.profile ./popcnt |
生产 cpu.profile
问价和popcnt.test
文件
1 | ➜ testBenchMark ll |
1 | go tool pprof popcnt.test cpu.profile 进入交互模式 |
1 | ➜ testBenchMark go tool pprof popcnt.test cpu.profile |
go tool pprof --web popcnt.test cpu.profile
进入web模式
1 | go tool pprof --text mybin http://myserver:6060:/debug/pprof/profile |
这有几个可用的输出类型,最有用的几个为: --text,--web 和 --list 。运行 go tool pprof
来得到最完整的列表。
下面分享一点go test
的参数解读。来源
格式形如:
1 | go test [-c] [-i] [build flags] [packages] [flags for test binary] |
参数解读:
-c : 编译go test成为可执行的二进制文件,但是不运行测试。
-i : 安装测试包依赖的package,但是不运行测试。
关于build flags,调用go help build,这些是编译运行过程中需要使用到的参数,一般设置为空
关于packages,调用go help packages,这些是关于包的管理,一般设置为空
关于flags for test binary,调用go help testflag,这些是go test过程中经常使用到的参数
-test.v : 是否输出全部的单元测试用例(不管成功或者失败),默认没有加上,所以只输出失败的单元测试用例。
-test.run pattern: 只跑哪些单元测试用例
-test.bench patten: 只跑那些性能测试用例
-test.benchmem : 是否在性能测试的时候输出内存情况
-test.benchtime t : 性能测试运行的时间,默认是1s
-test.cpuprofile cpu.out : 是否输出cpu性能分析文件
-test.memprofile mem.out : 是否输出内存性能分析文件
-test.blockprofile block.out : 是否输出内部goroutine阻塞的性能分析文件
-test.memprofilerate n : 内存性能分析的时候有一个分配了多少的时候才打点记录的问题。这个参数就是设置打点的内存分配间隔,也就是profile中一个sample代表的内存大小。默认是设置为512 * 1024的。如果你将它设置为1,则每分配一个内存块就会在profile中有个打点,那么生成的profile的sample就会非常多。如果你设置为0,那就是不做打点了。
你可以通过设置memprofilerate=1和GOGC=off来关闭内存回收,并且对每个内存块的分配进行观察。
-test.blockprofilerate n: 基本同上,控制的是goroutine阻塞时候打点的纳秒数。默认不设置就相当于-test.blockprofilerate=1,每一纳秒都打点记录一下
-test.parallel n : 性能测试的程序并行cpu数,默认等于GOMAXPROCS。
-test.timeout t : 如果测试用例运行时间超过t,则抛出panic
-test.cpu 1,2,4 : 程序运行在哪些CPU上面,使用二进制的1所在位代表,和nginx的nginx_worker_cpu_affinity是一个道理
-test.short : 将那些运行时间较长的测试用例运行时间缩短
例子
1 | // 压力测试 默认3s |