很多人做的测试表明,for的性能强于range,真的如此吗? 亲自做个测试。
三种遍历方式
func InSlice[T comparable](a T, s []T) bool {
for _, i := range s {
if a == i {
return true
}
}
return false
}
func InSlice1[T comparable](a T, s []T) bool {
for k, _ := range s {
if a == s[k] {
return true
}
}
return false
}
func InSlice2[T comparable](a T, s []T) bool {
l := len(s)
for i := 1; i < l; i++ {
if a == s[i] {
return true
}
}
return false
}
测试开始
// go test -bench='BenchmarkInSlice$' -count=10 .
// goos: darwin
// goarch: arm64
// pkg: github.com/lizongying/go-utils
// BenchmarkInSlice-10 5 207184892 ns/op
// BenchmarkInSlice-10 5 210529525 ns/op
// BenchmarkInSlice-10 5 204624450 ns/op
// BenchmarkInSlice-10 5 205362650 ns/op
// BenchmarkInSlice-10 5 203210925 ns/op
// BenchmarkInSlice-10 5 204164450 ns/op
// BenchmarkInSlice-10 5 201273425 ns/op
// BenchmarkInSlice-10 5 208560850 ns/op
// BenchmarkInSlice-10 5 207711300 ns/op
// BenchmarkInSlice-10 5 206910067 ns/op
// PASS
// ok github.com/lizongying/go-utils 22.205s
func BenchmarkInSlice(b *testing.B) {
for n := 0; n < b.N; n++ {
var a []int
for i := 1; i < 100000000; i++ {
a = append(a, i)
}
InSlice(100000000, a)
}
}
// go test -bench='BenchmarkInSlice1' -count=10 .
// goos: darwin
// goarch: arm64
// pkg: github.com/lizongying/go-utils
// BenchmarkInSlice1-10 5 206318867 ns/op
// BenchmarkInSlice1-10 5 207953442 ns/op
// BenchmarkInSlice1-10 5 207148500 ns/op
// BenchmarkInSlice1-10 5 214083775 ns/op
// BenchmarkInSlice1-10 5 211576917 ns/op
// BenchmarkInSlice1-10 5 225982375 ns/op
// BenchmarkInSlice1-10 5 231619367 ns/op
// BenchmarkInSlice1-10 5 207295975 ns/op
// BenchmarkInSlice1-10 5 213262542 ns/op
// BenchmarkInSlice1-10 5 214848125 ns/op
// PASS
// ok github.com/lizongying/go-utils 23.100s
func BenchmarkInSlice1(b *testing.B) {
for n := 0; n < b.N; n++ {
var a []int
for i := 1; i < 100000000; i++ {
a = append(a, i)
}
InSlice1(100000000, a)
}
}
// go test -bench='BenchmarkInSlice2' -count=10 .
// goos: darwin
// goarch: arm64
// pkg: github.com/lizongying/go-utils
// BenchmarkInSlice2-10 5 204758850 ns/op
// BenchmarkInSlice2-10 5 203728883 ns/op
// BenchmarkInSlice2-10 5 201642900 ns/op
// BenchmarkInSlice2-10 5 207764067 ns/op
// BenchmarkInSlice2-10 5 206985317 ns/op
// BenchmarkInSlice2-10 5 206063683 ns/op
// BenchmarkInSlice2-10 5 203198800 ns/op
// BenchmarkInSlice2-10 5 202168783 ns/op
// BenchmarkInSlice2-10 5 208278617 ns/op
// BenchmarkInSlice2-10 5 201505567 ns/op
// PASS
// ok github.com/lizongying/go-utils 22.244s
func BenchmarkInSlice2(b *testing.B) {
for n := 0; n < b.N; n++ {
var a []int
for i := 1; i < 100000000; i++ {
a = append(a, i)
}
InSlice2(100000000, a)
}
}
这是一个真实场景,结论是range性能更好,多次测试结果一致。 为什么有区别呢?
1.本例子中1和3相比:range忽略了index,实际上index在大多是场景下也是非必要的。range不需要计算长度 2.本例子中1和2相比:1不用根据index再获取值 3.本例子中2确实不如3
所以在通常场景下,如果不需要获取index,range还方便,为什么不用呢? 当然,当元素比较大非指针的情况下,range可能不如for,暂未测试。