go test - 基准测试

ddatsh

dev #go go-test

稳定的测试环境

性能测试受环境影响很大,为保证测试的可重复性,尽可能地保持测试环境的稳定

规则

// fib.go
package main

func Fib(n int) int {

	if n == 0 || n == 1 {
		return n
	}
	return Fib(n-2) + Fib(n-1)
}
// fib_test.go
package main

import "testing"

func BenchmarkFib(b *testing.B) {
	for n := 0; n < b.N; n++ {
		Fib(30) // run fib(30) b.N times
	}
}

默认 go test 会运行单元测试,可以使用-run=匹配一个从来没有的单元测试方法,过滤掉单元测试的输出(如 -run=^$)

go test -run=XXX -bench=. -benchmem -cpuprofile cpu.out -memprofile mem.out

benchmark 默认至少运行1秒。 -benchtime=Ns 指定具体运行时间

-count=N 表示运行该基准测试多少次。注意:不是多少次op或迭代

函数名后的数字表示 GOMAXPROCS 的值,默认是 CPU 的核数。该值可以在执行测试时设置,例如 GOMAXPROCS=2 go test ...

benchstat

go install golang.org/x/perf/cmd/benchstat@latest
package main
import "testing"
//go:noinline
func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}
var Result int
func BenchmarkMax(b *testing.B) {
    var r int
    for i := 0; i < b.N; i++ {
        r = max(-1, i)
    }
    Result = r
}
go test -bench=.  -count=10  -gcflags="-l -N"  > base.txt
go test -bench=.  -count=10  > noinline.txt
go test -bench=.  -count=10  > inline.txt
benchstat base.txt noinline.txt  inline.txt
goos: windows
goarch: amd64
pkg: test
cpu: 13th Gen Intel(R) Core(TM) i5-13600KF
       │   base.txt   │             noinline.txt             │              inline.txt              │
       │    sec/op    │    sec/op     vs base                │    sec/op     vs base                │
Max-20   0.9940n ± 1%   0.4947n ± 1%  -50.23% (p=0.000 n=10)   0.1358n ± 1%  -86.33% (p=0.000 n=10)

如果 delta 一列,值是~,没有显示百分比,说明两次测试结果没有显著差异

go test -cover

ref

The Cover Story