GO基准测试
作者:互联网
基准测试就是在一定的工作负载之下检测程序性能的一种方法
基准测试用例约定
- 基准测试以Benchmark为前缀
- 需要一个*testing.B类型的参数b
- 基准测试必须要执行b.N次
testing.B的拥有的方法如下:
func (c *B) Error(args ...interface{})
func (c *B) Errorf(format string, args ...interface{})
func (c *B) Fail()
func (c *B) FailNow()
func (c *B) Failed() bool
func (c *B) Fatal(args ...interface{})
func (c *B) Fatalf(format string, args ...interface{})
func (c *B) Log(args ...interface{})
func (c *B) Logf(format string, args ...interface{})
func (c *B) Name() string
func (b *B) ReportAllocs()
func (b *B) ResetTimer()
func (b *B) Run(name string, f func(b *B)) bool
func (b *B) RunParallel(body func(*PB))
func (b *B) SetBytes(n int64)
func (b *B) SetParallelism(p int)
func (c *B) Skip(args ...interface{})
func (c *B) SkipNow()
func (c *B) Skipf(format string, args ...interface{})
func (c *B) Skipped() bool
func (b *B) StartTimer()
func (b *B) StopTimer()
动手环节
编写基准测试代码
// fib.go
package main
import "fmt"
func fib(n int) int {
if n == 0 || n == 1 {
return n
}
return fib(n-2) + fib(n-1)
}
func main() {
fmt.Println(fib(10))
}
// fib_test.go
package main
import "testing"
func BenchmarkFib(b *testing.B) {
for n := 0; n < b.N; n++ {
fib(30)
}
}
// 测试
go test -bench=Fib -run=none
go test -bench=Fib -run=none -benchmem
go test -benchmem -bench=. -run=none
测试命令
$ go test -bench=Fib
goos: windows
goarch: amd64
pkg: test
BenchmarkFib-8 228 5253644 ns/op
PASStest
ok test 1.785s
// 结果解析
BenchmarkFib-8 表示对Fib函数进行基准测试,数字8表示 GOMAXPROCS 的值
5253644 ns/op 表示每次调用Fib函数耗时5253644ns
228 这是228次调用的平均值
-benchmem 参数展示内存消耗情况
$ go test -bench=Fib -benchmem
goos: windows
goarch: amd64
pkg: test
BenchmarkFib-8 198 6503562 ns/op 0 B/op 0 allocs/op
PASStest
ok test 1.785s
// 结果解析
0 B/op 表示每次操作内存分配了0字节
0 allocs/op 表示每次操作进行了0次内存分配
-cpu 不同核心cpu结果
go test -bench=Fib -cpu=1 -benchmem
-count 连续跑N次
go test -bench=Fib -count=10 -benchmem
-benchtime 指定运行秒数
go test -bench=Fib -benchtime=10s -benchmem
问题:-run=none参数有什么用?
go test -bench=Fib -run=none // 结果?
测试函数传参-性能测试
很多性能问题是发生在两个不同操作之间的相对耗时,比如同一个函数处理1000个元素的耗时与处理10000甚至100000个元素的耗时的差别是多少?
再或者对于同一个任务究竟使用哪种算法性能最佳?
我们通常需要对两个不同算法的实现使用相同的输入来进行基准比较测试
package main
import (
"testing"
)
func Add(n int) int {
tmp := 0
for i := 0; i <= n; i++ {
tmp = tmp + i
}
return tmp
}
func benchmarkAdd(i int, b *testing.B) {
for n := 0; n < b.N; n++ { // b.N你觉得是什么
Add(i)
}
}
func BenchmarkAdd1000(b *testing.B) { benchmarkAdd(1000, b) }
func BenchmarkAdd10000(b *testing.B) { benchmarkAdd(10000, b) }
func BenchmarkAdd100000(b *testing.B) { benchmarkAdd(100000, b) }
bench测试
$ go test -bench=.
goos: linux
goarch: amd64
pkg: test
cpu: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
BenchmarkGenerate1000-8 3997779 303.6 ns/op
BenchmarkGenerate10000-8 402241 2889 ns/op
BenchmarkGenerate100000-8 42884 28545 ns/op
PASS
ok test 4.225s
// 默认情况下,每个基准测试至少运行1秒。如果在Benchmark函数返回时没有到1秒,则b.N的值会按1,2,5,10,20,50,…增加,并且函数再次运行。
-benchtime标志增加最小基准时间,以产生更准确的结果
$ go test -bench=. -benchtime=20s
goos: linux
goarch: amd64
pkg: test
cpu: Intel(R) Core(TM) i7-4790 CPU @ 3.60GHz
BenchmarkAdd1000-8 81030480 293.2 ns/op
BenchmarkAdd10000-8 8304865 2848 ns/op
BenchmarkAdd100000-8 846728 28599 ns/op
PASS
ok test 75.148s
b.ResetTimer-重置时间:一般加在不计划作为测试报告的操作之后
func benchmarkAdd(i int, b *testing.B) {
time.Sleep(1 * time.Second)
b.ResetTimer() // -----------------例子-------------------
for n := 0; n < b.N; n++ {
Add(i)
}
}
b.SetParallelism()-设置使用CPU数 // 加了实际没生效 go1.16版本 linux环境 建议使用命令行参数 -cpu=n
func benchmarkAdd(i int, b *testing.B) {
b.SetParallelism(2) // -----------------例子-------------------
for n := 0; n < b.N; n++ {
Add(i)
}
}
b.RunParallel()-并行测试:创建出多个goroutine,goroutine数量默认为 GOMAXPROCS 数量也就是CPU核数
// 例子
func benchmarkAdd(i int, b *testing.B) {
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Add(i)
}
})
}
// SetParallelism() 加了实际没生效 go1.16版本 linux环境
func benchmarkAdd(i int, b *testing.B) {
b.SetParallelism(1)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
Add(i)
}
})
}
// -cpu
go test -bench=. -cpu=1
go test -bench=. -cpu=2
go test -bench=. -cpu=4
go test -bench=. -cpu=8
标签:func,测试,基准,testing,bench,test,go,GO,op 来源: https://www.cnblogs.com/Otiger/p/16221889.html