Go test.B 基准测试是否可以防止不必要的优化?

Els*_*nor 7 go microbenchmark caliper

我最近开始学习 Go,我正在尝试实现一个可以由多个 groutine 同时使用的地图。我希望能够将我的实现与简单的sync.Mutex受保护的映射或类似的东西进行比较: https://github.com/streamrail/concurrent-map/blob/master/concurrent_map.go

通过使用 Google Caliper,我认为一种幼稚的基准测试方法会导致许多不需要的优化,从而破坏实际结果。使用的基准测试是否testing.B采用了一些技术来避免这种情况(毕竟 Go 和 Caliper 都是 Google 项目)?如果有,他们是已知的吗?如果不是,那么在 Go 中进行微基准测试的最佳方法是什么?

Joh*_*yil 4

将我的评论转换为答案。

为了完全准确,任何基准测试都应该小心避免编译器优化消除被测函数并人为地降低基准测试的运行时间。

var result int

func BenchmarkFibComplete(b *testing.B) {
        var r int
        for n := 0; n < b.N; n++ {
                // always record the result of Fib to prevent
                // the compiler eliminating the function call.
                r = Fib(10)
        }
        // always store the result to a package level variable
        // so the compiler cannot eliminate the Benchmark itself.
        result = r
}
Run Code Online (Sandbox Code Playgroud)

来源

以下页面也很有用。

编译器和运行时优化

另一个有趣的读物是

另一个有趣的标志是 -N,它将禁用编译器中的优化过程。

来源1 来源2

我不是 100% 确定,但以下应该禁用优化?需要更有经验的人来证实一下。

go test -gcflags=-N -bench=.
Run Code Online (Sandbox Code Playgroud)