其他分享
首页 > 其他分享> > GO基准测试

GO基准测试

作者:互联网

基准测试就是在一定的工作负载之下检测程序性能的一种方法

基准测试用例约定

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