网站域名能更该吗,河南网站建设外贸,扶贫工作网站建设方案,空间注册网站在前一篇文章中#xff0c;我们讲解了Go语言中最基础的单元测试#xff0c;还没有看过的可以自行去查看#xff0c;这篇文章我们详细了解Go语言里面的基准测试。 基准测试
基准测试#xff0c;也就是BenchmarkTest#xff0c;基准测试是用来测试代码性能的的一种方法我们讲解了Go语言中最基础的单元测试还没有看过的可以自行去查看这篇文章我们详细了解Go语言里面的基准测试。 基准测试
基准测试也就是BenchmarkTest基准测试是用来测试代码性能的的一种方法使用基准测试时测试函数必须以Benchmark开头后面跟具体需要测试的函数的名称基本格式如下
// Add函数对应的基准测试函数
func BenchmarkAdd(b *testing.B){}基准测试函数中的参数是b *testing.B基准测试时函数必须要执行b.N次只有这样测试才能具有参考性和一定的准确性。b.N这个值并不是固定的而是根据情况变化从1开始如果当前测试函数能够在1秒内执行完毕则会将b.N的值增加到2如果测试函数同样在1秒内执行完毕则会继续增加b.N的值b.N的递增序列为1,2,3,5,10,20,30,50,100。
基本使用
现在我们先写一个计算斐波拉契数列的函数
// Fib 递归函数计算斐波拉契数列的第 x 个数
func Fib(x int) int {if x 1 {return x}return Fib(x-1) Fib(x-2)
}然后在对应的测试文件中写上针对Fib函数的基准测试函数
func BenchmarkFib(b *testing.B) {for i : 0; i b.N; i {Fib(10)}
}在功能函数和基准测试函数都准备完毕之后我们可以使用go test命令来执行对应的基准测试使用该命令不能直接运行基准测试需要在参数后面指定-bench参数并指定响应的函数名称。
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib-8 4861580 235.1 ns/op
PASS
ok test/calc 1.567s上面的输出中上面都是一些系统相关信息下面BenchmarkFib-8后面的数字表示的是GOMAXPROCS默认等于CPU的核数后面的4861580和235.1 ns/op表示当前测试用例执行的4861580次平均花费时间为235.1 ns总耗时为1.567s。 在使用的时候还可以通过其他参数来获取更多的测试数据用来提升测试的准确率和可参考性。 使用-benchmem参数来获取内存分配的数据。
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib -benchmem
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib-8 4749666 251.0 ns/op 0 B/op 0 allocs/op
PASS
ok test/calc 1.609s在耗时的后面新增了0 B/op和0 allocs/op其中0 B/op表示每次运行测试分配了0B的内存0 allocs/op表示每次运行测试进行了0次的内存分配因为我们的功能函数没用到额外的内存所以这两个值都是0大家可以自己尝试其他方法来看看这个值的变化。 使用-benchtime参数指定测试的基准时间或次数在前面我们说过测试用例会执行b.N次这个数量是动态变化的只要运行测试用例的时间没有超过1秒就会递增这个值。现在可以使用-benchtime参数指定这个基准时间如果修改为5可以使用-benchtime5s则表示执行时间不超过5秒就会递增b.N。
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib -benchtime5s
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib-8 23184202 235.6 ns/op
PASS
ok test/calc 5.859s通过上面的输出可以看到一共运行了23184202次平均每次耗时235.6 ns总耗时5.859s。因为通过-benchtime指定了基准时间为5秒所以总运行次数大概是之前的5倍。 -benchtime除了指定时间之外还可以用来指定具体的次数假设指定执行100次可以使用-benchtime100x
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib -benchtime100x
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib-8 100 487.0 ns/op
PASS
ok test/calc 0.167s上面可以看到通过-benchtime指定次数后一共调用了Fib函数100次总耗时0.167s。 -count参数可以用来指定测试的轮数比如指定执行3轮。
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib -count3
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib-8 4641591 261.0 ns/op
BenchmarkFib-8 5031808 238.0 ns/op
BenchmarkFib-8 5103565 245.1 ns/op性能比较
在基准测试中某些功能函数在不同的输入时相对应的性能也会有所差别在前面的所有测试中我们传递的参数都是10也就是每次都计算的是斐波拉契数列的第10个如果我们需要测试一个函数在不同的输入下的性能差异或者是测试两个函数在相同输入下的性能差异就会使用到性能比较的测试方法在比较性能的时候就需要使用到一个带参数的测试函数再使用其他的Benchmark函数传入不同的值来调用用以测试不同输入的性能差别。 我们将上面的测试代码修改如下
func benchmarkFib(b *testing.B, n int) {for i : 0; i b.N; i {Fib(n)}
}func BenchmarkFib2(b *testing.B) {benchmarkFib(b, 2)
}func BenchmarkFib10(b *testing.B) {benchmarkFib(b, 10)
}func BenchmarkFib20(b *testing.B) {benchmarkFib(b, 20)
}func BenchmarkFib30(b *testing.B) {benchmarkFib(b, 30)
}在代码中写了一个带有参数的辅助函数benchmarkFib可以传入参数并且构造了4个测试用例分别传入不同的参数执行上面的测试用例。
PS C:\Users\lee\GolandProjects\test\calc go test -benchFib
goos: windows
goarch: amd64
pkg: test/calc
cpu: Intel(R) Core(TM) i7-9700 CPU 3.00GHz
BenchmarkFib2-8 304879520 3.793 ns/op
BenchmarkFib10-8 5249786 232.8 ns/op
BenchmarkFib20-8 41760 28409 ns/op
BenchmarkFib30-8 345 3571588 ns/op
PASS
ok test/calc 6.245s可以看到在不同的输入下函数的执行次数和平均执行时间都有不小的差距当计算第30个数的时候一共才执行了345次而每次的平均执行时间为3571588 ns。
重置时间
在进行基准测试的时候通常都是用来测试函数的性能我们上面的函数都是简单的一些示例但是在日常的工作中我们测试之前可能需要有一些准备工作例如测试前读取文件这样的话在测试的时候就会将读取文件的耗时也计算到测试报告里面去这个时候我们可以使用到ResetTimer来重置时间代码如下
func BenchmarkFib(b *testing.B) {// sleep 3秒模拟测试前的准备工作time.Sleep(time.Second * 3)// 重置定时器b.ResetTimer()for i : 0; i b.N; i {Fib(10)}
}在代码中调用了b.ResetTimer()方法这样就表示重置定时器意味着这行代码之前的所有代码的耗时都不会被计算到测试中这样能够确保代码测试的准确性。