为了账号安全,请及时绑定邮箱和手机立即绑定

golang:如何解释类​​型断言效率?

golang:如何解释类​​型断言效率?

Go
SMILET 2021-10-25 16:22:21
类型断言将涉及对 runtime.assertE2T 或 runtime.assertE2I 的调用(您可以看到汇编代码)。package mainimport (    "fmt"    "time")type I interface {    echo()}type A struct{}func (a *A) echo() {}type testfn func()func run(f testfn) {    ts := time.Now()    f()    te := time.Now()    fmt.Println(te.Sub(ts))}func testE2T() {    var i interface{} = new(A)    for a := 0; a < 500000000; a++ {        _ = i.(*A)    }}func testE2I() {    var i interface{} = new(A)    for a := 0; a < 500000000; a++ {        _ = i.(I)    }}func main() {    fmt.Println("testE2I:")    run(testE2I)    fmt.Println("testE2T:")    run(testE2T)}结果:testE2I:11.065225934stestE2T:5.720773381s似乎类型断言比 C 中的指针转换慢?怎么解释?而且奇怪的是,当我使用gccgo运行相同的程序时,会导致内存不足错误。gccgo 在 gc 中有一些限制吗?
查看完整描述

1 回答

?
慕标5832272

TA贡献1966条经验 获得超4个赞

我不太清楚你的主要问题是什么,但我会尽量回答你提出的问题。

似乎类型断言比 C 中的指针转换慢?

是的。类型断言在运行时需要是安全的,因此它们需要执行许多检查。接口到接口断言更糟糕,因为您还需要确保类型实现了接口。

话虽如此,他们绝对可以表现得更好。事实上,这是您在 Go 1.4.2 上的基准测试结果的比较。与 Go 1.5 的最新开发版本对比:

  • 转到 1.4.2: testE2I: 10.014922955s, testE2T: 4.465621814s

  • 转到 1.5 开发: testE2I: 7.201485053s, testE2T: 287.08346ms

它现在快了十倍以上,而且 Go 1.6 的新 SSA 后端可能会带来更好的优化。

而且奇怪的是,当我使用gccgo运行相同的程序时,会导致内存不足错误。gccgo 在 gc 中有一些限制吗?

我猜这是 gccgo 缺乏逃逸分析,但我可能错了。我实际上能够在我的机器上使用 gccgo 运行基准测试,但它消耗了大约 9 GB 的 RAM,这很正常。我很确定提交一个问题不会有什么坏处。无论如何,这是结果-O3

  • gccgo: testE2I: 30.405681s, testE2T: 1.734307s

在具体类型上更快,但在接口到接口断言时要慢得多。


查看完整回答
反对 回复 2021-10-25
  • 1 回答
  • 0 关注
  • 225 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信