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

栏目: IT技术 · 发布时间: 6年前

内容简介:推荐阅读
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

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

事有蹊跷,必是优化!

搜索发现相关 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]

参考资料

[1]

Devirtualize calls when concrete type behind interface is statically known: https://github.com/golang/go/issues/19361

[2]

De-virtualize interface calls: https://go-review.googlesource.com/c/go/+/37751

[3]

Use devirtualization in escape analysis: https://github.com/golang/go/issues/33160

[4]

Go compiler: https://github.com/golang/go/blob/7145f1c7c7dcd4506f2819166f073e92f57afbb7/src/cmd/compile/README.md

[5]

Devirtualize的测试代码: https://golang.org/test/devirt.go

[6]

NewbMiao/Dig101-Go: https://github.com/NewbMiao/Dig101-Go/blob/master/types/interface/interface.go

推荐阅读

欢迎关注我,一位爱折腾的开发( 奶爸 ):热爱搬砖、价投,不定期分享技术。 Dig101: Go 之 interface 调用的一个优化点

原创不易,如果有用,欢迎点个  在看   让给更多的人看到

微信内外链不能跳转,戳  阅读原文   查看原文中参考资料


以上所述就是小编给大家介绍的《Dig101: Go 之 interface 调用的一个优化点》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

数据挖掘导论

数据挖掘导论

Pang-Ning Tan, Michael Steinbach / 范明 范宏建 / 人民邮电出版社 / 2006-01-01 / 49.00元

本书全面介绍了数据挖掘的理论和方法,旨在为读者提供将数据挖掘应用于实际问题所必需的知识。本书涵盖五个主题:数据、分类、关联分析、聚类和异常检测。除异常检测外,每个主题都包含两章:前面一章讲述基本概念、代表性算法和评估技术,后面一章较深入地讨论高级概念和算法。目的是使读者在透彻地理解数据挖掘基础的同时,还能了解更多重要的高级主题。此外,书中还提供了大量示例、图表和习题。 本书适合作为......一起来看看 《数据挖掘导论》 这本书的介绍吧!

HTML 压缩/解压工具
HTML 压缩/解压工具

在线压缩/解压 HTML 代码

RGB转16进制工具
RGB转16进制工具

RGB HEX 互转工具

html转js在线工具
html转js在线工具

html转js在线工具