в производительности for range, когда используется копирование значения, и обращение к указателю
По моей логике, первый бенчмарк должен отработать хуже, т.к
for _, v := range numbers
копирует значение по индексу из numbers в v
func BenchmarkForCopyArrayValue(b *testing.B) {
numbers := [...]int{1, 2, 3, 4, 5}
for i := 0; i < b.N; i++ {
for _, v := range numbers {
temp := v
_ = temp
}
}
}
func BenchmarkForCopyArrayValuePointer(b *testing.B) {
numbers := [...]int{1, 2, 3, 4, 5}
for i := 0; i < b.N; i++ {
for i := range numbers {
temp := numbers[i]
_ = temp
}
}
}
BenchmarkForCopyArrayValue-8 549499458 2.179 ns/op 0 B/op 0 allocs/op
BenchmarkForCopyArrayValuePointer-8 545401737 2.159 ns/op 0 B/op 0 allocs/op
так там же, вроде, в обоих случаях копирование из массива по индексу, но в одном случае это делается внутри рейнджа, а во втором случае это делается в теле цикла я ничего не гарантирую
Спасибо за ответ
Так а где здесь указатель?
если массив хранится в куче, то указатель на массив. Я не знаю точно, как это в го работает хотя если массив на стеке, то там... ну, не знаю, смотря как указатель рассматривать. Ну, типа, оффсет - это же тоже в какой-то степени указатель... я, опять же, ничего не гарантирую, но в данном случае могу ещё и сильно промахнуться
Конкретно в коде который приведет выше, указатель в принципе не используется. Аллокация происходит на стеке что в бенчмарке по указателю, что по значению. Конкретно для текущего примера нету вообще никакого смысла использовать аллокацию на куче, так как время GC будет забирать больше времени чем процесс обращения по стеку
Какой бенч - такие и результаты
1) Надо сделать 2 отдельные реализации и в них уже передавать массив по указателю 2) Массив надо делать более жирным(допустим, на 1m элементов) 3) Лучше считать какую-то сумму элементов итп.
Спасибо попробую
Обсуждают сегодня