go語言遍歷切片的時候有range,和for下標兩種遍歷方法,那麼哪種性能好呢?直覺上,range是對元素的拷貝,性能必然不如for+下標訪問效率高。且看下面的測試。
測試環境
goos: linux
goarch: amd64
go version go1.14 linux/amd64
Run on (8 X 2394.37 MHz CPU s)
CPU Caches:
L1 Data 32 KiB (x8)
L1 Instruction 32 KiB (x8)
L2 Unified 4096 KiB (x8)
L3 Unified 16384 KiB (x1)
測試代碼
BufSize模擬切片中每個元素的大小。
ArrSize表示數組大小。 這裏取1000,因爲循環本身也會有消耗。
//src/benchmark/range_test.go
package main
import (
"testing"
)
const (
BufSize=256
ArrSize=1000
)
type Buff struct {
data [BufSize]uint8
}
func BenchmarkRange(b *testing.B) {
var SomeData = make([]Buff, ArrSize)
for i := 0; i < b.N; i ++ {
for _, d := range SomeData {
_ = len(d.data)
}
}
}
func BenchmarkFor(b *testing.B) {
var SomeData = make([]Buff, ArrSize)
for i := 0; i < b.N; i ++ {
for j:=0; j < len(SomeData); j++ {
_ = len(SomeData[j].data)
}
}
}
go test -v -bench="(Range)|(For)"
測試結果
StructSize | Range ns/op | For ns/op |
0 | 399 | 346 |
1 | 389 | 350 |
2 | 379 | 390 |
4 | 385 | 384 |
8 | 343 | 346 |
16 | 342 | 342 |
32 | 343 | 342 |
64 | 343 | 342 |
72 | 362 | 400 |
76 | 374 | 384 |
80 | 3375 | 342 |
96 | 4173 | 341 |
128 | 5035 | 343 |
256 | 9415 | 345 |
ArrSize: | 1000 |
測試結論
當數組元素大小小於76字節時,兩者性能一樣。大於76字節時,for range性能明顯下降。