8.4.6 总结
深入了解编译器内联机制之后,我们可以写出更加益于编译器优化的代码。例如我们有一个很复杂的函数:
func ReallyBigFunc() {
// Part 1: Fast Operations with few statements
// stmt0
// stmt1
result := expr()
if result {
return
}
// Part 2: Slow operations with many statements
// stmt4
// stmt5
// ...
// stmt100
}
假设该函数使用得极其频繁,而大多数情况下函数都会在第一个
if
语句处返回,只有极少数情况下需要执行后面的 Slow Operation. 由于函数的总体复杂度很大,因此编译器不会对其进行内联,所以程序在执行时需要付出很大的调用开销。一个优化的策略是让编译器将 Part 1 的代码进行内联,我们可以将 Part 2 单独提取为一个函数:func slowOp() {
// Part 2: Slow operations with many statements
// stmt4
// stmt5
// ...
// stmt100
}
func ReallyBigFunc() {
// Part 1: Fast Operations with few statements
// stmt0
// stmt1
result := expr()
if !result {
slowOp()
}
}
func main() {
ReallyBigFunc()
}
这样函数
ReallyBigFunc()
的行为不会改变但复杂度降低,对于每个调用函数 ReallyBigFunc()
的地方编译器都可以将其内联。例如上面的 main
函数最终会是如下样子:func main() {
// Part 1: Fast Operations with few statements
// stmt0
// stmt1
result := expr()
if !result {
slowOp()
}
}
这样就极大地避免了原函数的调用开销。