内容简介:推荐阅读
Dig101: dig more, simplified more and know more
今天谈下上文( Dig101:Go之读懂interface的底层设计 )留下的那个问题:
为什么对于以下 interface Stringer
和构造类型 Binary
下面代码 conversion
会调用转换函数 convT64
,而 devirt
不会调用?
func conversion() { var b Stringer var i Binary = 1 b = i //convT64 _ = b.String() } func devirt() { var b Stringer = Binary(1) _ = b.String() //static call Binary.String }
这里可以使用 ssa 可视化 工具 查看,更容易了解每行代码的编译过程
如
GOSSAFUNC=main go1.14 build types/interface/interface.go
生成 ssa.html
事有蹊跷,必是优化!
搜索发现相关 issue Devirtualize calls when concrete type behind interface is statically known [1] 和提交 De-virtualize interface calls [2]
原来这个是为了优化如果 interface 内部的构造类型如果可以内联后被静态推断出来的话,就将其直接重写为静态调用
最初主要希望避免一些 interface 调用的 gc 压力(interface 调用在逃逸分析时,会使函数的接受者( receiver
)和参数( argument
)逃逸到堆上(而不是留在栈上),增加 gc 压力。不过这一点目前还未实现,参见 Use devirtualization in escape analysis [3] )
暂时先优化为静态调用避免转换调用( convXXX
),减少代码大小和提升细微的性能
摘录主要处理点如下:
// 对iface=类指针(pointer-shaped)构造类型 记录itab // 用于后续优化掉 OCONVIFACE cmd/compile/internal/gc/subr.go:implements if isdirectiface(t0) && !iface.IsEmptyInterface() { itabname(t0, iface) } cmd/compile/internal/gc/reflect.go:itabname itabs = append(itabs, itabEntry{t: t, itype: itype, lsym: s.Linksym()}) // 编译前,获取itabs cmd/compile/internal/gc/reflect.go:peekitabs // ssa时利用函数内联和itabs推断可重写为静态调用,避免convXXX cmd/compile/internal/ssa/rewrite.go:devirt
Go 编译步骤相关参见 Go compiler [4]
这种优化对于常见的返回 interface 的构造函数还是有帮助的。
func New() Interface { return &impl{...} }
要注意返回构造类型需为 类指针 才可以。
我们可以利用这一点来应用此 interface 调用优化
想了解更多,可以查看 Devirtualize 的测试代码 [5]
本文代码见 NewbMiao/Dig101-Go [6]
参考资料
Devirtualize calls when concrete type behind interface is statically known: https://github.com/golang/go/issues/19361
De-virtualize interface calls: https://go-review.googlesource.com/c/go/+/37751
Use devirtualization in escape analysis: https://github.com/golang/go/issues/33160
Go compiler: https://github.com/golang/go/blob/7145f1c7c7dcd4506f2819166f073e92f57afbb7/src/cmd/compile/README.md
Devirtualize的测试代码: https://golang.org/test/devirt.go
NewbMiao/Dig101-Go: https://github.com/NewbMiao/Dig101-Go/blob/master/types/interface/interface.go
推荐阅读
欢迎关注我,一位爱折腾的开发( 奶爸 ):热爱搬砖、价投,不定期分享技术。
原创不易,如果有用,欢迎点个 在看 , 让给更多的人看到
微信内外链不能跳转,戳 阅读原文 查看原文中参考资料
以上所述就是小编给大家介绍的《Dig101: Go 之 interface 调用的一个优化点》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 直观讲解-RPC调用和HTTP调用的区别
- 调用链系列一:解读UAVStack中的调用链技术
- 调用链系列二:解读UAVStack中的调用链技术
- 调用链系列三:解读UAVStack中的调用链技术
- dubbo源码解析(二十七)远程调用——injvm本地调用
- 微服务间的调用和应用内调用有什么区别
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
电子邮件营销密码
[美] Jeanniey Mullen、David Daniesl / 薛剑韬 / 人民邮电出版社 / 2009-9 / 39.00元
在当今互联网蓬勃发展的形势下,电子邮件是互联网应用最广的服务之一。那么如何利用其作为有效的营销工具呢?本书系统地讲解了美国电子邮件营销的预算统筹、营销策略、管理模式、执行机制、涉及的技术、营销实施的细节等,其方法有很强的可循性,并可预见将获得的成果。阅读本书之后,读者会深刻感受到电子邮件营销的博大精深,它既是一门扎实严谨的科学,又是一项充满创造力的艺术。. 本书适合企业管理人员及市场营销人员......一起来看看 《电子邮件营销密码》 这本书的介绍吧!