Loading... # 什么是内联优化 内联是一个基本的编译器优化,他会将一些简单的函数展开放入程序主题中,减少调用函数本身的开销。 # 内联优化有什么好处 用 Go 写一个例子分别测试开启与不开启内联优化的性能对比 ```go func maxInline(a, b int) int { if a > b { return a } else { return b } } //go:noinline func maxNoInline(a, b int) int { if a > b { return a } else { return b } } func BenchmarkNoInline(b *testing.B) { var res int for i := 0; i < b.N; i++ { res = maxNoInline(-1, i) } print(res) } func BenchmarkInline(b *testing.B) { var res int for i := 0; i < b.N; i++ { res = maxInline(-1, i) } print(res) } ``` 结果如下: ```bash BenchmarkNoInline-12 716281923 1.69 ns/op BenchmarkInline-12 1000000000 0.488 ns/op ``` # 内联优化怎么做的 其实原理非常简单,就是把函数拆开放到了调用者的代码段里,比如我们上面的例子 ```go // 不使用内联优化 func maxNoInline(a, b int) int { if a > b { return a } else { return b } } func BenchmarkNoInline(b *testing.B) { var res int for i := 0; i < b.N; i++ { res = maxNoInline(-1, i) } print(res) } // 使用内联优化 func BenchmarkInline(b *testing.B) { var res int for i := 0; i < b.N; i++ { if -1 > i { res = -1 } else { res = i } } print(res) } ``` # 为什么使用内联优化性能提升这么大 我们的代码最终是由 CPU 执行的,而 CPU 只能执行汇编指令,并且同一时间内一颗 CPU 核心只能执行一条汇编指令。这就意味着 CPU 要执行的汇编指令条数越少,程序耗时也就越少。而函数调用对应 `CALL` 指令,每多执行一次函数调用则会让 CPU 多执行一条指令,量级越大性能差异也越大。 下面我们用一款 Steam 上模拟 CPU 执行汇编指令的游戏 [Human Resource Machine](https://store.steampowered.com/app/375820/Human_Resource_Machine/),来解释内联优化~ > 因为游戏中没有 CALL 指令,所以我们用 JUMP 代替 这里也是一个简单的 `max` 函数例子,要求从左边的 InBox 拿两个数比较大小,然后将最大的那个放入右边的 OutBox,同时手里只能拿一个数。当然以下的例子不是这个游戏的最优解~有兴趣的同学可以自己试试 ## 不使用内联优化的例子   比较 8 个数,总共执行了46步。 ## 使用内联优化   比较 8 个数,使用内联优化总共执行了38步。 最后修改:2021 年 08 月 17 日 09 : 48 AM © 允许规范转载 赞赏 如果觉得我的文章对你有用,请随意赞赏 赞赏作者 支付宝微信