Hi everyone,
I have a piece of code which is behaving a bit strangely in benchmarks. Here is a simplified version of it.
The only difference is that in one case, the destination is a different slice. On the other case, its the same slice as source.
func BenchmarkStringCreate(b *testing.B) {
for n := 0; n < b.N; n++ {
DecodeStringCreate("ab")
}
}
func BenchmarkStringNoCreate(b *testing.B) {
for n := 0; n < b.N; n++ {
DecodeStringNoCreate("ab")
}
}
func DecodeStringCreate(str string) []byte {
dst := make([]byte, 2)
src := []byte(str)
Decode(dst, src)
return dst
}
func DecodeStringNoCreate(str string) []byte {
src := []byte(str)
Decode(src, src)
return src
}
func Decode(dst, src []byte) {
for i := 0; i < 1; i++ {
dst[0] = src[0]
}
}
BenchmarkStringCreate-4 50000000 37.2 ns/op 2 B/op 1 allocs/op
BenchmarkStringNoCreate-4 30000000 44.3 ns/op 8 B/op 1 allocs/op
PASS
ok stdtest 3.279s
It seems very strange to me that on the case where I am not allocating any slice, allocates 8 bytes of memory, whereas, when I create the slice of 2, it clearly allocates only 2 bytes.
Now here is the fun part, if I change the Decode function to remove the for loop, all allocations go down to zero.
func Decode(dst, src []byte) {
dst[0] = src[0]
}
BenchmarkStringCreate-4 100000000 10.2 ns/op 0 B/op 0 allocs/op
BenchmarkStringNoCreate-4 200000000 9.85 ns/op 0 B/op 0 allocs/op
PASS
ok stdtest 4.000s
How come removing the for loop changes the no. of allocations ? And the loop always runs only 1 iteration anyway. I have no clue as to what is happening here.
Any help will be appreciated.
Thanks.