在Go中使用类型断言/类型switch 作为运行时类型发现方法的速度有多慢?

例如,我听说在C/C++中,在运行时发现类型的性能很差.为了绕过这一点,您通常会向类中添加类型成员,这样就可以与这些成员进行比较,而不是强制转换.

我还没有在整个www上找到一个明确的答案.

这里有一个我想问的例子--与其他类型判断方法(比如上面提到的,或者我不知道的其他方法)相比,这算不算fast

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()
        }
    }
}

EDIT Oct. 09, 2019

看来,上述方法是平等的,彼此之间没有优势.以下是我的机器(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

PREVIOUS RESULTS on Jan. 19, 2015

在我的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++是否更慢,或者您的应用程序是否可以容忍这种速度.

Go相关问答推荐

Golang ==错误:OCI运行时创建失败:无法启动容器进程:exec:./" bin:stat./" bin:没有这样的文件或目录:未知

Go Colly-访问for循环中的URL

为什么要立即调用内联函数,而不仅仅是调用其包含的函数?

Go 是否提供了标准或事实上的方法来处理单个语句中的错误(即内联错误处理)?

无法读取postman 中的表单数据

如何测试 Zerolog 记录器引发类型错误的日志(log)事件?

如何绕过深层 xml,没有嵌套循环?

Docker 执行失败并显示cmd/ENTRYPOINT 中的命令未找到

Go Template 动态获取变量

Go Template if 条件

Gorm 在自定义字符串类型上返回 scanner 错误

GOLANG:为什么 SetDeadline/SetReadDeadline/SetWriteDeadline 在使用 os.File.Fd() 时对文件不起作用?

emersion/go-imap - imap.FetchRFC822:无效内存地址或零指针取消引用

为超时的单元测试创​​建 deadlineExceededError:true

从 os.stdout 读取

Golang prometheus 显示自定义指标

测试包外文件时的 Golang 测试覆盖率

Go模板中的浮点除法

无法识别同步错误.使用一次

带有 *s3.S3 对象的 Golang 单元测试