ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

GO基准测试

2022-05-04 18:31:25  阅读:170  来源: 互联网

标签:func 测试 基准 testing bench test go GO op


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

基准测试用例约定

  • 基准测试以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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有