类型断言/类型切换是否性能不佳/在 Go 中运行缓慢? [英] Does a type assertion / type switch have bad performance / is slow in Go?

查看:36
本文介绍了类型断言/类型切换是否性能不佳/在 Go 中运行缓慢?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

How slow is using type assertions / type switches in Go, as a method of run-time type discovery?

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

I've heard that in C/C++ for example, discovering types at run time has bad performance. To bypass that, you usually add type members to classes, so you can compare against these instead of casting.

我在整个 www 中都没有找到明确的答案.

I haven't found a clear answer for this throughout the www.

这是我要问的一个示例 - 与其他类型检查方法(如上面提到的或我不知道的其他方法)相比,这是否被认为 快速?

Here's an example of what I'm asking about - Is this considered fast when compared to other type checking methodologies (like mentioned above, or others I'm not aware of)?

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

推荐答案

很容易写一个Benchmark测试来检查它:http://play.golang.org/p/E9H_4K2J9-

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

2019 年 10 月 9 日编辑

上面展示的方法似乎是相同的,彼此之间没有优势.以下是我机器上的结果(AMD R7 2700X,Golang v1.12.9):

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

再次:

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 机器上,我得到以下时间:

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

所以看起来通过类型切换或类型断言访问方法比直接或通过接口调用方法慢大约 5-6 倍.

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.

我不知道 C++ 是否较慢,或者您的应用程序是否可以容忍这种减速.

I don't know if C++ is slower or if this slowdown is tolerable for your application.

这篇关于类型断言/类型切换是否性能不佳/在 Go 中运行缓慢?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆