编译优化
概述
在 Go 编译器中,-N 标志用于禁用所有优化。虽然官方文档没有详细列出所有具体的优化内容,但可以大致概括为以下几类:
- 内联优化:函数调用的内联化,即将小函数的代码直接插入到调用点,减少函数调用的开销。
- 逃逸分析:确定哪些变量可以分配在栈上,哪些需要分配在堆上。禁用优化后,更多的变量可能会分配到堆上,增加垃圾收集的负担。
- 循环优化:包括循环展开和循环不变代码外提等优化。
- 常量折叠和传播:将常量表达式在编译时进行计算,减少运行时的计算开销。
- 死代码消除:移除永远不会执行的代码。
- 寄存器分配优化:优化寄存器的使用,减少内存访问次数。
禁用这些优化会使生成的代码更容易调试,因为编译器不会重排代码或内联函数调用,调试器可以更准确地映射源代码到生成的机器代码。不过,这也会导致生成的代码运行效率降低,主要表现在以下几个方面:
禁用内联的影响
内联优化是将小函数的代码直接插入到调用点,避免函数调用的开销。禁用内联会有以下影响:
- 增加函数调用开销:每次函数调用都需要保存和恢复调用者的状态(如寄存器、栈帧等),增加了运行时开销。
- 减少指令级并行性:内联后的代码可以更好地利用处理器的指令级并行性,禁用内联可能会导致处理器流水线效率降低。
- 影响编译器的进一步优化:内联后的代码可以暴露更多的优化机会,例如跨函数的常量传播和死代码消除等。禁用内联可能会阻碍这些优化。
- 增加代码的可读性和可维护性:内联会增加生成的代码体积,禁用内联可以使生成的代码更紧凑,但这通常不是性能优化的目标。
优化策略
内联优化
逃逸分析
详见 逃逸分析