美文网首页
Golang中的benchmark

Golang中的benchmark

作者: 小餐包 | 来源:发表于2022-05-19 21:32 被阅读0次

知识点:

  • benchmark函数以Benchmark开头而非 Test开头.
  • 通过为go test命令添加-bench标记的方式运行benchmark测试,参数的值是一个正则表达式,如果运行全部benchmark测试,则指定为-bench=.即可;
  • 为了避免普通的测试case被执行,可以加上-run=^$(匹配空函数)来跳过执行;
  • 如果希望同步观察内存使用,可以通过-benchmem标记位来实现;
  • 为了确保结果的一致性,可以加上-count参数来重复运行benchmark;
  • 每个benchmark默认情况下会运行至少一分钟,我们可以通过 -benchtime标记位来生成一个更准确的结果;
  • b.N 的值会以1, 2, 5, 10, 20, 50, …这样的规律递增下去直到运行时间超过或等于1秒钟(可以通过上面的 -benchtime修改),这里不是时间一到就截止,运行期还会综合运行时间的稳定性来判断是否继续;
  • 接上一条,由于程序判断运行时间稳定才会停止运行,所以千万不要在loop循环里面使用一个变化的值作为函数的参数,这里要注意b.N是也是一个动态变化的值!

例子:

func benchmarkFib(i int, b *testing.B) {
        for n := 0; n < b.N; n++ {
                Fib(i)
        }
}
func BenchmarkFib1(b *testing.B)  { benchmarkFib(1, b) }
func BenchmarkFib2(b *testing.B)  { benchmarkFib(2, b) }
func BenchmarkFib3(b *testing.B)  { benchmarkFib(3, b) }
func BenchmarkFib10(b *testing.B) { benchmarkFib(10, b) }
func BenchmarkFib20(b *testing.B) { benchmarkFib(20, b) }
func BenchmarkFib40(b *testing.B) { benchmarkFib(40, b) }

得到结果:

BenchmarkFib1   1000000000               2.84 ns/op
BenchmarkFib2   500000000                7.92 ns/op
BenchmarkFib3   100000000               13.0 ns/op
BenchmarkFib10   5000000               447 ns/op
BenchmarkFib20     50000             55668 ns/op
BenchmarkFib40         2         942888676 ns/op

说明:

  • 第一列是执行的函数名称,第二列是总的执行次数,第三列是平均运行时间;

引申:

上面也可以用table driven的方式来运行多个case,这里类似于t.Run方法,需要使用 b.Run方法来执行多个case比如:

func BenchmarkFib(b *testing.B) {
    var table = []struct {
        input int
    }{
        {input: 10},
        {input: 20},
        {input: 50},
        {input: 100},
    }
    for _, v := range table {
        b.Run(fmt.Sprintf("input_size_%d", v.input), func(b *testing.B) {
            for i := 0; i < b.N; i++ {
                uniquePaths(v.input, v.input)
            }
        })
    }
}

参考文献:

相关文章

网友评论

      本文标题:Golang中的benchmark

      本文链接:https://www.haomeiwen.com/subject/ibcxprtx.html