类型断言将涉及对 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
在具体类型上更快,但在接口到接口断言时要慢得多。
- 1 回答
- 0 关注
- 225 浏览
添加回答
举报
0/150
提交
取消