• Daniel Martí's avatar
    expose APIs without Reader/Writer overhead · 8ec6b0fb
    Daniel Martí authored
    An io.Writer, by definition, will always copy bytes. That's fine in
    general, and can't be worked around without breaking the writer's
    contract.
    
    However, the main use of go-codec-dagpb today is go-merkledag, which
    simply uses the codec to encode a node into a buffer.
    
    So, we had to create a new bytes.Buffer, write to it, and grab its
    bytes. This is one extra allocation (the bytes.Buffer object itself),
    plus copying the encoded bytes an extra time, since we must copy from
    Encode's internal buffer to the bytes.Buffer.
    
    Add a lower-level append-like AppendEncode that cuts the middle man,
    removing both of those extra pieces of work.
    
    For the sake of consistency, we add DecodeBytes to mirror the above on
    the decode side. Decode already had a shortcut for Bytes, but this way
    it's more evident what we're doing, and we also avoid allocating a
    bytes.Buffer just to call Bytes on it.
    
    Using these new APIs in go-merkledag shows nice results:
    
    	name         old time/op    new time/op    delta
    	Roundtrip-8    4.27µs ± 0%    4.07µs ± 0%  -4.50%  (p=0.004 n=5+6)
    
    	name         old alloc/op   new alloc/op   delta
    	Roundtrip-8    6.86kB ± 0%    6.38kB ± 0%  -6.99%  (p=0.002 n=6+6)
    
    	name         old allocs/op  new allocs/op  delta
    	Roundtrip-8       106 ± 0%       103 ± 0%  -2.83%  (p=0.002 n=6+6)
    
    While at it, we formally deprecate Marshal and Unmarshal, since we're
    starting to have lots of redundant API surface.
    8ec6b0fb
multicodec.go 1.52 KB