用于循环速度比较

时间:2019-05-21 05:07:49

标签: performance go performance-testing

我想知道len运算符在Go中的运行速度如何,我编写了一个简单的基准测试。我的期望是,通过避免在每次循环迭代期间都调用len,代码可以更快地运行,但实际上相反。

这里是基准:

func sumArrayNumber(input []int) int {
    var res int
    for i, length := 0, len(input); i < length; i += 1 {
        res += input[i]
    }
    return res
}

func sumArrayNumber2(input []int) int {
    var res int
    for i := 0; i < len(input); i += 1 {
        res += input[i]
    }
    return res
}

var result int
var input = []int{3, 6, 22, 68, 11, -7, 22, 5, 0, 0, 1}

func BenchmarkSumArrayNumber(b *testing.B) {
    var r int
    for n := 0; n < b.N; n++ {
        r = sumArrayNumber(input)
    }
    result = r
}

func BenchmarkSumArrayNumber2(b *testing.B) {
    var r int
    for n := 0; n < b.N; n++ {
        r = sumArrayNumber2(input)
    }
    result = r
}

结果如下:

goos: windows
goarch: amd64
BenchmarkSumArrayNumber-8       300000000                4.75 ns/op
BenchmarkSumArrayNumber2-8      300000000                4.67 ns/op
PASS
ok      command-line-arguments  4.000s

我通过执行以下操作确认了电阻是一致的:

  • 将输入数组的大小加倍大约会使每个操作的执行时间加倍。速度差随输入数组的长度成比例。
  • 交换测试订单不会影响结果。

为什么每次循环迭代时检查len()的代码都更快?

1 个答案:

答案 0 :(得分:0)

一个人可能会说,0.08ns的差异与一个for循环要快于另一个for循环没有统计学意义。您可能需要多次运行同一测试(至少超过20次),此时您应该能够得出平均值和标准差。

此外,有许多因素可以加快len()运算符的速度。像CPU缓存和编译器优化。我认为在您的特定示例中,最相关的因素是切片和数组的len()运算符仅读取slice数据结构中的len字段。因此,它是O(1)。