dphj737575 2016-12-13 11:15
浏览 61
已采纳

刺激代码内联

Unlike in languages like C++, where you can explicitly state inline, in Go the compiler dynamically detects functions that are candidate for inlining (which C++ can do too, but Go can't do both). Also there's a debug option to see possible inlining happening, yet there is very few documented online about the exact logic of the go compiler(s) doing this.

Let's say I need to rerun some big loop over a set of data every n-period;

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)
}

Aiming for example for Encrypt to being inlined properly what logic should I need to take into consideration for the compiler?

I know from C++ that passing by reference will increase likeliness for automatic inlining without the explicit inline keyword, but it's not very easy to understand what the compiler exactly does to determine the decisions on choosing to inline or not in Go. Scriptlanguages like PHP for example suffer immensely if you do a loop with a constant addSomething($a, $b) where benchmarking such a billion cycles the cost of it versus $a + $b (inline) is almost ridiculous.

  • 写回答

2条回答 默认 最新

  • dongshenling6585 2016-12-13 11:27
    关注

    Quoting minux (on 2013-01-31):

    By default, the inliner will try to inline leaf function (doesn't call other functions/method/interfaces) that doesn't call panic or recover or select or switch or create closure or go/defer functions (see example below) and which is less than 40 nodes when represented (roughly corresponding to 40 simple operations). But please beware that this only describes the current status quo of the gc compiler, and it will surely improve in the future. Thus please try not to depend on this.

    Until you have performance problems, you shouldn't care. Inlined or not, it will do the same.

    If performance does matter and it makes a noticable and significant difference, then don't rely on current (or past) inlining conditions, "inline" it yourself (do not put it in a separate function).

    The rules can be found in the $GOROOT/src/cmd/compile/internal/gc/inl.go file. You may control its aggressiveness with the 'l' debug flag.

    // 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.
    

    Also check out blog post: Dave Cheney - Five things that make Go fast (2014-06-07) which writes about inlining (long post, it's about in the middle, search for the "inline" word).

    Also interesting discussion about inlining improvements (maybe Go 1.9?): cmd/compile: improve inlining cost model #17566

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 iOS开发关于快捷指令截屏后如何将截屏(或从截屏中提取出的文本)回传给本应用并打开指定页面
  • ¥15 unity连接Sqlserver
  • ¥15 图中这种约束条件lingo该怎么表示出来
  • ¥15 VSCode里的Prettier如何实现等式赋值后的对齐效果?
  • ¥15 流式socket文件传输答疑
  • ¥20 keepalive配置业务服务双机单活的方法。业务服务一定是要双机单活的方式
  • ¥50 关于多次提交POST数据后,无法获取到POST数据参数的问题
  • ¥15 win10,这种情况怎么办
  • ¥15 如何在配置使用Prettier的VSCode中通过Better Align插件来对齐等式?(相关搜索:格式化)
  • ¥100 在连接内网VPN时,如何同时保持互联网连接