check byte) bool{
return val & check != 0
}
val := byte(0)
for i := 0; i < b.N; i++ {
checkSingle(val, 1)
checkSingle(val, 2)
checkSingle(val, 3)
}
}
func BenchmarkMulti(b *testing.B) {
checkMulti := func(val byte, checks ...byte) bool{
for _, check := range checks{
if val & check != 0{
return true
}
}
return false
}
val := byte(0)
for i := 0; i < b.N; i++ {
checkMulti(val, 1, 2, 3)
}
}
Результат
BenchmarkSingle-4 1000000000 0.610 ns/op
BenchmarkMulti-4 75690834 14.0 ns/op
Почему такая большая разница?
Как минимум засчёт вот этого check := range checks
организация цикла чего-то стоит и это всегда надо помнить. плюс, у тебя фактические ручной loop unrolling, который компилятор не умеет делать.
я чуть-чуть поигрался с твоим примером: https://play.golang.org/p/5e_Cb327kQN
я думаю, в первую очередь — аллокация, вариадики под капотом это слайс по факту
https://go.godbolt.org/z/KbdFtb - инлайнится (22 строка аллокация в хипе) https://go.godbolt.org/z/kA8ztB - не инлайнится так работает оптимизатор SSA, видимо из-за цикла, нужно почитать ещё. Даже если возвращать результат перед циклом (то есть цикл не будет исполняться никогда), всё равно будет аллокация.
Обсуждают сегодня