Skip to content

Commit

Permalink
avoid double alloc in NewCidV1
Browse files Browse the repository at this point in the history
We allocate once via "make([]byte, len)",
and again when that buffer is converted to a string.

Thankfully, since Go 1.10 we have strings.Builder,
designed specifically for this use case.

In a downstream benchmark in go-car,
which needs to reconstruct many CID values,
we see small but nice gains:

    name           old time/op    new time/op    delta
    ReadBlocks-16    1.09ms ± 4%    1.06ms ± 5%   -3.33%  (p=0.007 n=11+11)

    name           old speed      new speed      delta
    ReadBlocks-16   478MB/s ± 4%   494MB/s ± 5%   +3.46%  (p=0.007 n=11+11)

    name           old alloc/op   new alloc/op   delta
    ReadBlocks-16    1.30MB ± 0%    1.25MB ± 0%   -3.86%  (p=0.000 n=12+12)

    name           old allocs/op  new allocs/op  delta
    ReadBlocks-16     9.50k ± 0%     8.45k ± 0%  -11.05%  (p=0.000 n=12+12)
  • Loading branch information
mvdan committed Sep 12, 2021
1 parent cf76220 commit 5640b01
Showing 1 changed file with 15 additions and 6 deletions.
21 changes: 15 additions & 6 deletions cid.go
Expand Up @@ -22,6 +22,7 @@ package cid
import (
"bytes"
"encoding"
"encoding/binary"
"encoding/json"
"errors"
"fmt"
Expand Down Expand Up @@ -173,16 +174,24 @@ func NewCidV0(mhash mh.Multihash) Cid {
// Panics if the multihash is invalid.
func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
hashlen := len(mhash)
// two 8 bytes (max) numbers plus hash
buf := make([]byte, 1+varint.UvarintSize(codecType)+hashlen)
n := varint.PutUvarint(buf, 1)
n += varint.PutUvarint(buf[n:], codecType)
cn := copy(buf[n:], mhash)

// Two 8 bytes (max) numbers plus hash.
// We use strings.Builder to only allocate once.
var b strings.Builder
b.Grow(1 + varint.UvarintSize(codecType) + hashlen)

b.WriteByte(1)

var buf [binary.MaxVarintLen64]byte
n := varint.PutUvarint(buf[:], codecType)
b.Write(buf[:n])

cn, _ := b.Write(mhash)
if cn != hashlen {
panic("copy hash length is inconsistent")
}

return Cid{string(buf[:n+hashlen])}
return Cid{b.String()}
}

var (
Expand Down

0 comments on commit 5640b01

Please sign in to comment.