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

类型断言将涉及对 runtime.assertE2T 或 runtime.assertE2I 的调用(您可以看到汇编代码)。


package main


import (

    "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.065225934s

testE2T:

5.720773381s

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


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


SMILET
浏览 226回答 1
1回答

慕标5832272

我不太清楚你的主要问题是什么,但我会尽量回答你提出的问题。似乎类型断言比 C 中的指针转换慢?是的。类型断言在运行时需要是安全的,因此它们需要执行许多检查。接口到接口断言更糟糕,因为您还需要确保类型实现了接口。话虽如此,他们绝对可以表现得更好。事实上,这是您在 Go 1.4.2 上的基准测试结果的比较。与 Go 1.5 的最新开发版本对比:转到 1.4.2:&nbsp;testE2I: 10.014922955s, testE2T: 4.465621814s转到 1.5 开发:&nbsp;testE2I: 7.201485053s, testE2T: 287.08346ms它现在快了十倍以上,而且 Go 1.6 的新 SSA 后端可能会带来更好的优化。而且奇怪的是,当我使用gccgo运行相同的程序时,会导致内存不足错误。gccgo 在 gc 中有一些限制吗?我猜这是 gccgo 缺乏逃逸分析,但我可能错了。我实际上能够在我的机器上使用 gccgo 运行基准测试,但它消耗了大约 9 GB 的 RAM,这很正常。我很确定提交一个问题不会有什么坏处。无论如何,这是结果-O3:gccgo:&nbsp;testE2I: 30.405681s, testE2T: 1.734307s在具体类型上更快,但在接口到接口断言时要慢得多。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go