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:projectgosrcawesomeProject2inlineaction>go test -run=none -bench=BenchmarkMax -count=10 > new.txt

D:projectgosrcawesomeProject2inlineaction>go test -run=none -bench=BenchmarkMax -count=10 > old.txt

D:projectgosrcawesomeProject2inlineaction>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
原文地址:https://www.cnblogs.com/CherryTab/p/12777307.html