在Go中使用类型断言/类型切换作为运行时类型发现的方法有多慢?
我听说例如在C / C ++中,在运行时发现类型会降低性能。要绕过它,通常将类型成员添加到类中,以便可以与这些类型进行比较而不是强制转换。
我在整个www上都没有找到明确的答案。
这是我要问的一个示例- 与其他类型检查方法(如上面提到的或我不知道的其他方法)相比,这是否算 快 ?
func question(anything interface{}) { switch v := anything.(type) { case string: fmt.Println(v) case int32, int64: fmt.Println(v) case SomeCustomType: fmt.Println(v) default: fmt.Println("unknown") } }
编写基准测试来检查它很容易:http : //play.golang.org/p/E9H_4K2J9-
package main import ( "testing" ) type myint int64 type Inccer interface { inc() } func (i *myint) inc() { *i = *i + 1 } func BenchmarkIntmethod(b *testing.B) { i := new(myint) incnIntmethod(i, b.N) } func BenchmarkInterface(b *testing.B) { i := new(myint) incnInterface(i, b.N) } func BenchmarkTypeSwitch(b *testing.B) { i := new(myint) incnSwitch(i, b.N) } func BenchmarkTypeAssertion(b *testing.B) { i := new(myint) incnAssertion(i, b.N) } func incnIntmethod(i *myint, n int) { for k := 0; k < n; k++ { i.inc() } } func incnInterface(any Inccer, n int) { for k := 0; k < n; k++ { any.inc() } } func incnSwitch(any Inccer, n int) { for k := 0; k < n; k++ { switch v := any.(type) { case *myint: v.inc() } } } func incnAssertion(any Inccer, n int) { for k := 0; k < n; k++ { if newint, ok := any.(*myint); ok { newint.inc() } } }
编辑2019年10月09日
看来上面演示的方法是平等的,彼此之间没有优势。这是我的机器(AMD R7 2700X,Golang v1.12.9)的结果:
BenchmarkIntmethod-16 2000000000 1.67 ns/op BenchmarkInterface-16 1000000000 2.03 ns/op BenchmarkTypeSwitch-16 2000000000 1.70 ns/op BenchmarkTypeAssertion-16 2000000000 1.67 ns/op PASS
然后再次:
BenchmarkIntmethod-16 2000000000 1.68 ns/op BenchmarkInterface-16 1000000000 2.01 ns/op BenchmarkTypeSwitch-16 2000000000 1.66 ns/op BenchmarkTypeAssertion-16 2000000000 1.67 ns/op
上一个结果:2015年1月19日
在我的amd64机器上,我得到以下计时:
$ go test -bench=. BenchmarkIntmethod 1000000000 2.71 ns/op BenchmarkInterface 1000000000 2.98 ns/op BenchmarkTypeSwitch 100000000 16.7 ns/op BenchmarkTypeAssertion 100000000 13.8 ns/op
因此,看起来像通过类型切换或类型声明访问方法比直接或通过接口调用方法要慢5-6倍。
我不知道C ++的速度是否较慢,或者这种减速度是否可以容忍您的应用程序。