Inlining optimisations in Go
原文链接
https://dave.cheney.net/2020/04/25/inlining-optimisations-in-go
本文主要讲了解释了下内联,这种基本属于编译器的事情,没有编译器基础的话,可以当个扫盲看,并不难。
package inlineaction import "testing" //go:noinline func max(a, b int) int { if a > b { return a } return b } var Result int func BenchmarkMax(b *testing.B) { var r int for i := 0; i < b.N; i++ { r = max(-1, i) } Result = r }
可以看到我们有了一个禁止内联的注释,这里可以只隔离内联对max的影响,而不是使用-gcflags ='-l -N'全局禁用优化。//go:noinline
% go test -bench=. BenchmarkMax-4 530687617 2.24 ns/op
当我们取消//go:noinline
% go test -bench=. BenchmarkMax-4 1000000000 0.514 ns/op
差异很明显,为什么,还是因为不内联的话,会有切换开销,其实我们手动内联这段max也可以。
func BenchmarkMax(b *testing.B) { var r int for i := 0; i < b.N; i++ { if -1 > i { r = -1 } else { r = i } } Result = r }
其实再进一步优化
func BenchmarkMax(b *testing.B) { var r int for i := 0; i < b.N; i++ { r = i } Result = r }
一般比较是否优化,是采用benchstat,这里简单示例一下
D:\project\go\src\awesomeProject2\inlineaction>go test -run=none -bench=BenchmarkMax -count=10 > new.txt D:\project\go\src\awesomeProject2\inlineaction>go test -run=none -bench=BenchmarkMax -count=10 > old.txt D:\project\go\src\awesomeProject2\inlineaction>benchstat old.txt new.txt name old time/op new time/op delta Max-8 1.81ns ± 2% 0.43ns ± 3% -76.32% (p=0.000 n=10+10)
当然,如果测试要求比较严格,我这么做也是不合规范的,我们要考虑到系统噪音,可以借助perflock
占坑学一下编译原理。
一个没有高级趣味的人。
email:hushui502@gmail.com