与像C++这样可以显式声明的语言不同inline,在Go中,编译器会动态检测内联的候选函数(C++也可以这样做,但Go不能同时执行这两种操作).还有一个调试选项可以看到可能的内联发生,但是很少有人在线记录go编译器执行此操作的确切逻辑.
假设我需要在每个n周期重新运行一组数据的大循环;
func Encrypt(password []byte) ([]byte, error) {
return bcrypt.GenerateFromPassword(password, 13)
}
for id, data := range someDataSet {
newPassword, _ := Encrypt([]byte("generatedSomething"))
data["password"] = newPassword
someSaveCall(id, data)
}
Run Code Online (Sandbox Code Playgroud)
目的是为了Encrypt正确地内联编译器需要考虑哪些逻辑?
我从C++中知道,通过引用传递将增加自动内联的可能性,而不使用显式inline关键字,但是要理解编译器确切地确定选择内联与否的决策是什么并不容易.像PHP这样的脚本语言会受到极大的影响,如果你做一个常量循环,addSomething($a, $b)其中基准测试如此十亿次循环它的成本与$a + $b(内联)几乎是荒谬的.
icz*_*cza 10
引用minux(2013-01-31):
默认情况下,内联器将尝试内联叶函数(不调用其他函数/方法/接口),不会调用panic或者恢复或选择或切换或创建闭包或go/defer函数(参见下面的示例)表示时少于40个节点(大致对应于40个简单操作).但请注意,这只描述了gc编译器的当前现状,并且将来肯定会有所改进.因此,请尽量不依赖于此.
在你遇到性能问题之前,你应该不在乎.内联与否,它也会这样做.
如果性能确实很重要且它会产生明显的显着差异,那么就不要依赖于当前(或过去)的内联条件,自己"内联"它(不要将它放在单独的函数中).
规则可以在$GOROOT/src/cmd/compile/internal/gc/inl.go文件中找到.您可以使用'l'调试标志控制其侵略性.
// The inlining facility makes 2 passes: first caninl determines which
// functions are suitable for inlining, and for those that are it
// saves a copy of the body. Then inlcalls walks each function body to
// expand calls to inlinable functions.
//
// The debug['l'] flag controls the aggressiveness. Note that main() swaps level 0 and 1,
// making 1 the default and -l disable. -ll and more is useful to flush out bugs.
// These additional levels (beyond -l) may be buggy and are not supported.
// 0: disabled
// 1: 40-nodes leaf functions, oneliners, lazy typechecking (default)
// 2: early typechecking of all imported bodies
// 3: allow variadic functions
// 4: allow non-leaf functions , (breaks runtime.Caller)
//
// At some point this may get another default and become switch-offable with -N.
//
// The debug['m'] flag enables diagnostic output. a single -m is useful for verifying
// which calls get inlined or not, more is for debugging, and may go away at any point.
Run Code Online (Sandbox Code Playgroud)
另请参阅博客文章:戴夫切尼 - 有五件事让Go快速(2014-06-07)写了关于内联(长篇文章,它在中间,搜索"内联"一词).
关于内联改进的有趣讨论(也许是Go 1.9?):cmd/compile:改进内联成本模型#17566
| 归档时间: |
|
| 查看次数: |
544 次 |
| 最近记录: |