上一篇写了些简单的单元测试,这一篇来看看go
中的基准测试。在go
中基准测试也是开箱即用的。使用testing.B
结构对象。linux
咱们依然用上一篇的代码结构
│ main.go │ main_test.go main.go func JoinStrUseSprint(a,b string) string { return fmt.Sprintf("%s%s",a,b) } func JoinStrUseNor(a,b string) string { return a+b }
建立普通单元测试咱们使用TestFunc
来定义。建立基准测试咱们须要使用BenchmarkFunc
来定义。
func TestJoinStrUseNor(t *testing.T) { s := JoinStrUseNor("aaa","bbb") t.Log(s) } func TestJoinStrUseSprint(t *testing.T) { s := JoinStrUseSprint("aaa","bbb") t.Log(s) } func BenchmarkJoinStrUseNor(b *testing.B) { b.ResetTimer() for i:=0; i<b.N; i++{ JoinStrUseNor("aaa","bbb") } } func BenchmarkJoinStrUseSprint(b *testing.B) { b.ResetTimer() for i:=0; i<b.N; i++{ JoinStrUseSprint("aaa","bbb") } }
执行基础测试
go test -bench=. -benchtime=1s -benchmem -count=1 goos: linux goarch: amd64 pkg: test BenchmarkJoinStrUseNor-8 79888155 15.5 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrUseSprint-8 8956500 135 ns/op 40 B/op 3 allocs/op PASS ok test 2.930s
-bench=.
表示指定执行测试函数。.
表示执行全部,若是修改成go test -bench=BenchmarkJoinStrUseSprint
那么只会执行BenchmarkJoinStrUseSprint
。-benchtime=1s
指定执行时间为1s
-benchmem
显示内存状况-count=1
表示执行一次goos: linux
操做系统goarch: amd64
系统体系架构BenchmarkJoinStrUseNor-8
执行的函数名称以及对应的GOMAXPROCS
值。79888155
b.N
的值15.5 ns/op
执行一次函数所花费的时间0 B/op
执行一次函数分配的内存0 allocs/op
执行一次函数所分配的内存次数结果分析
经过上面的响应结果参数,咱们很容易得出拼接两个字符串直接用+
号链接,比使用fmt.Sprintf()
的性能高。golang
有时候由于一些因素的影响,咱们单次测试的结果可能不许备,这个时候咱们就须要进行屡次测试好比go test -bench=BenchmarkJoinStrUseSprint -benchtime=1s -benchmem -count=10
将测试的次数定义为10 或者更大,这个时候我就须要去分析这些结果获得相对正确的测试结果。可是这个时候时候若是咱们人工去分析,工做量无疑是很大的,并且很困难。这个时候咱们就能够借助一个工具 benchstat
。微信
benchstat
是Golang
官方推荐的一款命令行工具,能够针对一组或多组样本进行分析,若是同时分析两组样本(好比优化前和优化后),还能够给出性能变化结果。架构
安装
go get golang.org/x/perf/cmd/benchstat
ide
分析
func JoinStrOpt(a,b string) string { return fmt.Sprintf("%s%s",a,b) }
func BenchmarkJoinStrOpt(b *testing.B) { b.ResetTimer() for i:=0; i<b.N; i++{ JoinStrOpt("aaa","bbb") } }
before.txt
go test -bench=BenchmarkJoinStrOpt -benchmem -count=10 | tee before.txt goos: linux goarch: amd64 pkg: test BenchmarkJoinStrOpt-8 9143092 131 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9222475 131 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9344643 130 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9127231 131 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9223482 130 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9126334 131 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9364201 129 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9248034 130 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9034518 130 ns/op 40 B/op 3 allocs/op BenchmarkJoinStrOpt-8 9102846 130 ns/op 40 B/op 3 allocs/op PASS ok test 13.323s
benchstat before.txt name time/op JoinStrOpt-8 130ns ± 1% name alloc/op JoinStrOpt-8 40.0B ± 0% name allocs/op JoinStrOpt-8 3.00 ± 0%
能够看出benchstrat
会给我一个执行10测试的结果分析,平均数值以及波动数值。函数
对比分析
JoinStrUseNor
的内容func JoinStrOpt(a,b string) string { return a+b }
after.txt
>go test -bench=BenchmarkJoinStrOpt -benchmem -count=10 | tee after.txt goos: linux goarch: amd64 pkg: test BenchmarkJoinStrOpt-8 78033046 15.3 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 77211630 15.3 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 78088903 15.4 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 77907912 15.3 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 73805730 15.3 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 78508854 15.3 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 73493384 15.2 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 78618926 15.2 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 74973290 15.2 ns/op 0 B/op 0 allocs/op BenchmarkJoinStrOpt-8 79287993 15.4 ns/op 0 B/op 0 allocs/op PASS ok test 11.959s
>benchstat before.txt after.txt name old time/op new time/op delta JoinStrOpt-8 130ns ± 1% 15ns ± 1% -88.27% (p=0.000 n=10+10) name old alloc/op new alloc/op delta JoinStrOpt-8 40.0B ± 0% 0.0B -100.00% (p=0.000 n=10+10) name old allocs/op new allocs/op delta JoinStrOpt-8 3.00 ± 0% 0.00 -100.00% (p=0.000 n=10+10)
能够看到benchstat
会给我直观的展现出优化代码先后的优化差值。工具
对比值括号中的数据含义
p
表示结果的可信程度,p 值越大可信程度越低,统计学中一般把p=0.05作为临界值,超过此值说明结果不可信,多是样本过少等缘由。性能
n=10+10
表示采用的样本数,,就跟投票同样一般会去掉一个最高分,一个最低分。出于某些缘由(好比数据值反常,过大或太小),benchstat
会舍弃某些样本,本例中优化前,优化后的数据没有舍弃因此是10+10
.单元测试
参考资料
期待与您一块儿交流测试