для сравнения скорости петли - PullRequest
0 голосов
/ 21 мая 2019

Мне было интересно, насколько быстрым был оператор 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 голосов
/ 21 мая 2019

Можно утверждать, что разница в 0,08 нс не является статистически значимой, чтобы утверждать, что один цикл for быстрее другого. Вероятно, вам нужно выполнить один и тот же тест много раз (по крайней мере, более 20 раз), после чего вы сможете получить среднее значение и стандартное отклонение.

Более того, существует множество факторов, которые могут ускорить работу оператора len(). Как оптимизация кэша процессора и компилятора. Я думаю, что наиболее важным фактором в вашем конкретном примере является то, что оператор len() для слайса и массива просто читает поле len в структуре данных slice . Таким образом, это O (1).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...