Does a type assertion / type switch have bad performance / is slow in Go?

前端 未结 6 732
天涯浪人
天涯浪人 2020-12-07 22:04

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

6条回答
  •  南方客
    南方客 (楼主)
    2020-12-07 22:46

    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.

提交回复
热议问题