golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
124.21k stars 17.7k forks source link

encoding/binary: Write does not optimise the case of native-format slices #70503

Open jech opened 9 hours ago

jech commented 9 hours ago

Go version

go version go1.23.3 linux/amd64

Output of go env in your module/workspace:

Irrelevant, but happy to provide.

What did you do?

I wrote a (large) number of slices of little-endian IEEE floats using binary.Write on a little-endian machine. I was expecting the library to recognise that I was writing in the native format, and special-case the write. However, it did not, and the performance was about 3000 slower than expected.

https://go.dev/play/p/wNWegxHXjlG

What did you see happen?

BenchmarkPutFloats-8              196766          5958 ns/op     671.41 MB/s
BenchmarkPutFloatsUnsafe-8      465501314            2.246 ns/op    1781336.18 MB/s

What did you expect to see?

I was expecting the performance of the two implementations to be similar.

seankhliao commented 8 hours ago

what about binary.NativeEndian?

adonovan commented 8 hours ago

The reason for the difference is that binary.Write allocates a 4KB buffer for each call, and the allocation escapes by being passed to io.Writer.Write. On a little-endian machine the contents of memory in that buffer are identical to the original array, so the alloc could be avoided in that case.

jech commented 8 hours ago

what about binary.NativeEndian?

https://github.com/golang/go/blob/master/src/encoding/binary/native_endian_little.go#L9

dmitshur commented 1 hour ago

CC @griesemer.