在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 ++的速度是否较慢,或者这种减速度是否可以容忍您的应用程序。
类型断言(Type Assertion)是一个使用在接口值上的操作,用于检查接口类型变量所持有的值是否实现了期望的接口或者具体的类型。 在Go语言中类型断言的语法格式如下: value, ok := x.(T) 其中,x 表示一个接口的类型,T 表示一个具体的类型(也可为接口类型)。 该断言表达式会返回 x 的值(也就是 value)和一个布尔值(也就是 ok),可根据该布尔值判断 x 是否为 T
问题内容: 我正在阅读《 Go编程语言》中的类型断言,但不理解它们。 我了解有不同的方案: T是具体类型或接口 可以返回一个(确定值?)或两个(确定)值 这是我不明白的: 我为什么要使用它们? 他们到底返回什么? 我也用谷歌搜索这个话题,但仍然不明白。 问题答案: 一行: 断言这不是nil并且存储的值是type 。 我为什么要使用它们: 检查为零 检查它是否可转换(断言)为另一种类型 转换(断言)
问题内容: 我在Go中使用类型开关,例如以下代码: 有没有一种方法可以防止在将问题传递给另一个函数之前必须断言案件中的问题类型? 问题答案: 是的,分配类型切换的结果将为您提供断言的类型 http://play.golang.org/p/qy0TPhypvp
7.10. 类型断言 类型断言是一个使用在接口值上的操作。语法上它看起来像x.(T)被称为断言类型,这里x表示一个接口的类型和T表示一个类型。一个类型断言检查它操作对象的动态类型是否和断言的类型匹配。 这里有两种可能。第一种,如果断言的类型T是一个具体类型,然后类型断言检查x的动态类型是否和T相同。如果这个检查成功了,类型断言的结果是x的动态值,当然它的类型是T。换句话说,具体类型的类型断言从它的
编辑:OK,在typescript规范中有详细说明:类型断言
问题内容: 我已经创建了一个基于字符串的角色类型,现在我想通过实现Valuer和Scanner接口使其与数据库驱动程序一起使用 我不断收到错误: 我在这里做错了什么? 问题答案: 这是第一个功能的工作代码: 尽管您可能希望使用并返回一个错误来代替恐慌。 a的签名不是您给的,而是: 请注意,这不会处理或产生NULL值。