go 类型断言的消耗

转载自达达的博客

  • 在一些通用化的接口设计中,我们不得不用interface{}来代表任意类型,然后在接口内部用类型转换来判断具体类型,从而执行具体逻辑。但是类型判断是有性能代价的,如果能具像化的知道这个性能代价有多大,就可以帮助我们设计接口的时候判断应该怎么设计。

  • 下面是实验代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
package labs01

import "testing"

type InterfaceA interface {
AA()
}

type InterfaceB interface {
BB()
}

type A struct {
v int
}

func (a *A) AA() {
a.v += 1
}

type B struct {
v int
}

func (b *B) BB() {
b.v += 1
}

func TypeSwitch(v interface{}) {
switch v.(type) {
case InterfaceA:
v.(InterfaceA).AA()
case InterfaceB:
v.(InterfaceB).BB()
}
}

func NormalSwitch(a *A) {
a.AA()
}

func InterfaceSwitch(v interface{}) {
v.(InterfaceA).AA()
}

func Benchmark_TypeSwitch(b *testing.B) {
var a = new(A)

for i := 0; i < b.N; i++ {
TypeSwitch(a)
}
}

func Benchmark_NormalSwitch(b *testing.B) {
var a = new(A)

for i := 0; i < b.N; i++ {
NormalSwitch(a)
}
}

func Benchmark_InterfaceSwitch(b *testing.B) {
var a = new(A)

for i := 0; i < b.N; i++ {
InterfaceSwitch(a)
}
}
  • 执行结果:

    1
    2
    3
    4
    5
    6
    7
    dada-imac:misc dada$ go test -test.bench=".*" labs01
    testing: warning: no tests to run
    PASS
    Benchmark_TypeSwitch 50000000 33.0 ns/op
    Benchmark_NormalSwitch 2000000000 1.99 ns/op
    Benchmark_InterfaceSwitch 100000000 18.4 ns/op
    ok labs 7.741s
  • 结论:类型判断和类型转换这两个操作都比直接操作多几倍的消耗。