这是我参与「第五届青训营 」伴学笔记创作活动的第10天。
五、Go编译器优化
1.函数内联(Inlining)
内联:将被调用的函数体(callee)的副本替换到调用位置(callee)上,同时重写代码以反映参数的绑定。
优点:
- 消除函数调用的开销,例如传递参数,保存寄存器等
- 将过程间分析转换为过程内分析,帮助优化,例如逃逸分析
函数内联能多大程度影响性能?——使用micro-benchmark快速验证和对比性能优化结果
缺点:
- 函数体变大,instruction cache不友好
- 编译生成的Go镜像变大
函数内联在大多数情况下是正向优化
内联策略:调用和被调函数的规模;……
2.Beast Mode
Go语言内联受到的限制较多
- 语言特性,例如interface, defer等,限制了函数内联
- 内联策略非常保守
Beast mode调整函数内联的策略,使更多函数被关联
- 降低函数调用的开销
- 增加了其他优化的机会:逃逸分析
开销:
- Go镜像增加 ~10%
- 编译时间增加
3.逃逸分析
逃逸分析:分析代码中指针的动态作用域:指针在何处可以被访问
思路:
- 从对象分配处出发,沿着控制流,观察对象的数据流
- 若发现指针p在当前作用域s:
- 作为参数传递给其他函数
- 传递给全局变量
- 传递给其他的goroutine
- 传递给已逃逸的指针指向的对象
- 则指针p指向的对象逃逸出s,反之则没有逃逸出s
Beast mode:函数内联拓展了函数边界,更多对象不逃逸
优化:未逃逸的对象可以在栈上分配
- 对象在栈上分配和回收很快:移动sp
- 减少在heap上的分配,降低GC负担
六、总结
从性能优化讲起,介绍了自动内存管理以及Go中怎样优化内存管理。再介绍编译器原理及如何进行编译器优化。