Proposal Details
Hi,
I wrote a zero allocation marshaller with mus-go for a struct that contains a lot of time.Time
. Unfortunately, it still allocates because of time.MarshalBinary()
.
I played a bit with the standard library and implemented another version of time.MarshalBinary() ([]byte, error)
that does not allocate (see: https://github.com/sylr/go/commit/384f060cc8da29846bc381beadbd6881010ebb3f).
Here are the results:
goos: darwin
goarch: arm64
pkg: utils/nats
cpu: Apple M2
│ old.txt │ new5.txt │
│ sec/op │ sec/op vs base │
Encoders/mus/raw-8 15.259µ ± 91% 6.268µ ± 0% -58.92% (p=0.000 n=10)
│ old.txt │ new5.txt │
│ bytes │ bytes vs base │
Encoders/mus/raw-8 4.001Ki ± 0% 4.001Ki ± 0% ~ (p=1.000 n=10) ¹
¹ all samples are equal
│ old.txt │ new5.txt │
│ B/op │ B/op vs base │
Encoders/mus/raw-8 1.562Ki ± 0% 0.000Ki ± 0% -100.00% (p=0.000 n=10)
│ old.txt │ new5.txt │
│ allocs/op │ allocs/op vs base │
Encoders/mus/raw-8 100.0 ± 0% 0.0 ± 0% -100.00% (p=0.000 n=10)
I'm wondering if we could merge something like this, possible implementations I could think of are:
func(t time.Time) Read(p []byte) (int, error)
(what I implemented in https://github.com/sylr/go/commit/384f060cc8da29846bc381beadbd6881010ebb3f)func(t time.Time) ReadBinary(p []byte) (int, error)
(same as previous but does not satisfy io.Reader to avoid implementing a known interface for a specific encoding)- A separate wrapper.
type BinaryReader struct { Time }
func(r BinaryReader) Read(p []byte) (int, error)
Comment From: icholy
https://github.com/golang/go/issues/62384
Comment From: ianlancetaylor
I think this would be addressed more generally by #62384.