数据说话：Go语言的Switch和Map性能实测

func BenchmarkSwitch(b *testing.B) {
var n int

for i := 0; i < b.N; i++ {
switch i % 4 {
case 0:
n += f0(i)
case 1:
n += f1(i)
case 2:
n += f2(i)
case 3:
n += f3(i)
}
}

// n will never be < 0, but checking n should ensure that the entire benchmark loop can't be optimized away.
if n < 0 {
b.Fatal("can't happen")
}
}

func BenchmarkMapFunc4(b *testing.B) {
var n int

for i := 0; i < b.N; i++ {
n += Funcs[i%4](i)
}

// n will never be < 0, but checking n should ensure that the entire benchmark loop can't be optimized away.
if n < 0 {
b.Fatal("can't happen")
}
}

func f0(n int) int {
if n%2 == 0 {
return n
} else {
return 0
}
}

func noInline0(n int) int {
if n < 0 {
panic("can't happen - but should ensure this function is not inlined")
} else if n%2 == 0 {
return n
} else {
return 0
}
}

for i := 0; i < b.N; i++ {
switch i % 4 {
// ...
}
}

var ascInputs []int

func TestMain(m *testing.M) {
for i := 0; i < 4096; i++ {
ascInputs = append(ascInputs, i)
}

os.Exit(m.Run())
}

func BenchmarkSwitch(b *testing.B) {  // ...
for i := 0; i < b.N; i++ {
switch ascInputs[i%len(ascInputs)] % 4 {
// ...
}
// ...
}
}

var randInputs []int

func TestMain(m *testing.M) {
for i := 0; i < 4096; i++ {
randInputs = append(randInputs, rand.Int())
}

os.Exit(m.Run())
}

func BenchmarkSwitch(b *testing.B) {
// ...
for i := 0; i < b.N; i++ {
switch randInputs[i%len(ascInputs)] % 4 {
// ...
}
// ...
}
}

go test -c

\$ perf stat -e cache-references,cache-misses,branches,branch-misses ./go_map_vs_switch.test -test.bench=PredictableLookupMapNoInlineFunc512 -test.benchtime=5s

9,919,244,177      branches
10,675,162         branch-misses  # 0.11% of all branches

\$ perf stat -e cache-references,cache-misses,branches,branch-misses ./go_map_vs_switch.test -test.bench=UnpredictableLookupMapNoInlineFunc512 -test.benchtime=5s

3,618,549,427 branches
451,154,480 branch-misses  # 12.47% of all branches

0 条评论

相关文章

DAY57:阅读Execution Configuration

Any call to a __global__ function must specify the execution configuration for t...

753

30211

3787

Linux CFS调度器之虚拟时钟vruntime与调度延迟--Linux进程的管理与调度(二十六）

CFS为了实现公平，必须惩罚当前正在运行的进程，以使那些正在等待的进程下次被调度。

2234

4268

42116

【golang】调优工具 pprof

Golang 提供了 pprof 包（runtime/pprof）用于输出运行时的 profiling 数据，这些数据可以被 pprof 工具（或者 go to...

1493

3286

3267