Мне было интересно, насколько быстрым был оператор 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 () на каждой итерации цикла выполняется быстрее?