Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

proposal: time: add a non allocating way to marshal Time in the binary format #66972

Open
sylr opened this issue Apr 22, 2024 · 2 comments
Open
Labels
Milestone

Comments

@sylr
Copy link

sylr commented Apr 22, 2024

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: sylr@384f060).

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 sylr@384f060)
  • 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)
@sylr sylr added the Proposal label Apr 22, 2024
@gopherbot gopherbot added this to the Proposal milestone Apr 22, 2024
@icholy
Copy link

icholy commented Apr 23, 2024

#62384

@ianlancetaylor
Copy link
Contributor

I think this would be addressed more generally by #62384.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
Status: Incoming
Development

No branches or pull requests

4 participants