Dig101-Go 之 interface 调用的一个优化点

Dig101: dig more, simplified more and know more
今天谈下上文( Dig101-Go 之读懂 interface 的底层设计 )留下的那个问题:
为什么对于以下 interface Stringer
和构造类型 Binary
下面代码conversion
会调用转换函数convT64
,而devirt
不会调用?
这里可以使用 ssa 可视化工具查看,更容易了解每行代码的编译过程 如
GOSSAFUNC=main go1.14 build types/interface/interface.go
生成
ssa.html

事有蹊跷,必是优化!
搜索发现相关 issue Devirtualize calls when concrete type behind interface is statically known 和提交 De-virtualize interface calls
原来这个是为了优化如果 interface 内部的构造类型如果可以内联后被静态推断出来的话,就将其直接重写为静态调用
最初主要希望避免一些 interface 调用的 gc 压力(interface 调用在逃逸分析时,会使函数的接受者(receiver
)和参数(argument
)逃逸到堆上(而不是留在栈上),增加 gc 压力。不过这一点目前还未实现,参见Use devirtualization in escape analysis)
暂时先优化为静态调用避免转换调用(convXXX
),减少代码大小和提升细微的性能
摘录主要处理点如下:
Go 编译步骤相关参见 Go compiler
这种优化对于常见的返回 interface 的构造函数还是有帮助的。
要注意返回构造类型需为类指针才可以。
我们可以利用这一点来应用此 interface 调用优化
想了解更多,可以查看Devirtualize 的测试代码
本文代码见 NewbMiao/Dig101-Go
文章首发公众号:newbmiao
推荐阅读:Dig101-Go系列

版权声明: 本文为 InfoQ 作者【newbmiao】的原创文章。
原文链接:【http://xie.infoq.cn/article/573f4b865734d5a913debd4be】。文章转载请联系作者。
评论