Skip to content

Commit 5640b01

Browse files
committed
avoid double alloc in NewCidV1
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)
1 parent cf76220 commit 5640b01

File tree

1 file changed

+15
-6
lines changed

1 file changed

+15
-6
lines changed

cid.go

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ package cid
2222
import (
2323
"bytes"
2424
"encoding"
25+
"encoding/binary"
2526
"encoding/json"
2627
"errors"
2728
"fmt"
@@ -173,16 +174,24 @@ func NewCidV0(mhash mh.Multihash) Cid {
173174
// Panics if the multihash is invalid.
174175
func NewCidV1(codecType uint64, mhash mh.Multihash) Cid {
175176
hashlen := len(mhash)
176-
// two 8 bytes (max) numbers plus hash
177-
buf := make([]byte, 1+varint.UvarintSize(codecType)+hashlen)
178-
n := varint.PutUvarint(buf, 1)
179-
n += varint.PutUvarint(buf[n:], codecType)
180-
cn := copy(buf[n:], mhash)
177+
178+
// Two 8 bytes (max) numbers plus hash.
179+
// We use strings.Builder to only allocate once.
180+
var b strings.Builder
181+
b.Grow(1 + varint.UvarintSize(codecType) + hashlen)
182+
183+
b.WriteByte(1)
184+
185+
var buf [binary.MaxVarintLen64]byte
186+
n := varint.PutUvarint(buf[:], codecType)
187+
b.Write(buf[:n])
188+
189+
cn, _ := b.Write(mhash)
181190
if cn != hashlen {
182191
panic("copy hash length is inconsistent")
183192
}
184193

185-
return Cid{string(buf[:n+hashlen])}
194+
return Cid{b.String()}
186195
}
187196

188197
var (

0 commit comments

Comments
 (0)