GO 中的内联函数

内联函数定义

在 wiki 中可以找到相关定义

计算机科学中,内联函数(有时称作在线函数编译时期展开函数)是一种编程语言结构,用来建议编译器对一些特殊函数进行内联扩展(有时称作在线扩展);也就是说建议编译器将指定的函数体插入并取代每一处调用该函数的地方(上下文),从而节省了每次调用函数带来的额外时间开支。但在选择使用内联函数时,必须在程序占用空间和程序执行效率之间进行权衡,因为过多的比较复杂的函数进行内联扩展将带来很大的存储资源开支。另外还需要特别注意的是对递归函数的内联扩展可能引起部分编译器的无穷编译。

在两个 Function A , B 中,A 调用 B, 把 B 设置为内联函数时,在编译时,B 的函数体会被展开,插入到 A 调用 B 的地方。编译后的程序中并没有找到 B 函数的符号。

在 C/C++ 中, 用 inline 来显示的说明函数是内联的。

go 中的内联函数

在 go 中没有 inline 关键字来设置内联函数。 但是 go 编译器会对小函数进行内联优化。

直接编译 go build -o main .

使用 readelf 查看函数符号

发现并没有 functionA 符号。

使用 go tool objdump 来看下反编译后的代码

go tool objdump -s main main

我们看到 main 函数里没有对 functionA 的调用, 而是把 functionA 直接展开,被内联到 main 函数中了。 所以,也就没有 functionA 符号了。

如果想看 go 编译器做了什么优化,可以使用 gcflags 进行查看

go build -gcflags –help

gcflags 传递的是对go 编译器的选项, 和 查看 go tool compile 是一样的

使用 -m 可以打印出优化选项。

go build -gcflags -m -o main .

可以看到有 inline 的优化。

使用 -l 可以禁用 inline .

调用之后, 重新readelf 查看符号

可以看到有 functionA 的符号。

此条目发表在GO分类目录,贴了标签。将固定链接加入收藏夹。

发表评论

邮箱地址不会被公开。