How slow is using type assertions / type switches in Go, as a method of run-time type discovery?
I\'ve heard that in C/C++ for example, discovering types at run time
It is very easy to write a Benchmark test to check it: 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()
}
}
}
EDIT Oct. 09, 2019
It appears that the methods demonstrated above are equal and have no advantage over one another. Here are the results from my machine (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
AND AGAIN:
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
PREVIOUS RESULTS on Jan. 19, 2015
On my amd64 machine, I'm getting the following timing:
$ 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
So it looks like accessing the method via type switch or type assertion is about 5-6 times slower than calling the method directly or via interface.
I don't know if C++ is slower or if this slowdown is tolerable for your application.