Golang foreach的区别

时间:2017-11-06 12:15:13

标签: go

func Benchmark_foreach1(b *testing.B) {
        var test map[int]int
        test = make(map[int]int)
            for i := 0; i < 100000; i++ {
                        test[i] = 1
            }
            for i := 0; i < b.N; i++ {
                    for i, _ := range test {
                            if test[i] != 1 {
                                    panic("ds")
                            }
                    }
            }
}

func Benchmark_foreach2(b *testing.B) {
            var test map[int]int
            test = make(map[int]int)
            for i := 0; i < 100000; i++ {
                    test[i] = 1
            }
            for i := 0; i < b.N; i++ {
                    for _, v := range test {
                            if v != 1 {
                                    panic("heh")
                            }
                    }
            }
}

运行结果如下

goos: linux
goarch: amd64
Benchmark_foreach1-2         500           3172323 ns/op
Benchmark_foreach2-2        1000           1707214 ns/op

为什么foreach-2慢了?

2 个答案:

答案 0 :(得分:4)

我认为Benchmark_foreach2-2大约快2倍 - 每个操作需要1707214纳秒,第一个需要3172323.所以第二个快3172323 / 1707214 = 1.85倍。

原因:第二个不需要再次从内存中获取值,它已经在v变量中使用了值。

答案 1 :(得分:2)

test[k]中的BenchmarkForeachK语句需要时间来随机读取该值,因此BenchmarkForeachKBenchmarkForeachV,9362945 ns / op与4213940 ns / op相比需要更多时间。

例如,

package main

import "testing"

func testMap() map[int]int {
    test := make(map[int]int)
    for i := 0; i < 100000; i++ {
        test[i] = 1
    }
    return test
}

func BenchmarkForeachK(b *testing.B) {
    test := testMap()
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for k := range test {
            if test[k] != 1 {
                panic("eh")
            }
        }
    }
}

func BenchmarkForeachV(b *testing.B) {
    test := testMap()
    b.ReportAllocs()
    b.ResetTimer()
    for i := 0; i < b.N; i++ {
        for _, v := range test {
            if v != 1 {
                panic("heh")
            }
        }
    }
}

输出:

$ go test foreach_test.go -bench=.
BenchmarkForeachK-4    200    9362945 ns/op    0 B/op    0 allocs/op
BenchmarkForeachV-4    300    4213940 ns/op    0 B/op    0 allocs/op