Skip to content

Commit

Permalink
Optimize encodeUint (#2882)
Browse files Browse the repository at this point in the history
  • Loading branch information
StephenButtolph authored Mar 28, 2024
1 parent ec347cb commit 2a0bd08
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 17 deletions.
22 changes: 5 additions & 17 deletions x/merkledb/codec.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import (
"math"
"math/bits"
"slices"
"sync"

"golang.org/x/exp/maps"

Expand Down Expand Up @@ -75,22 +74,12 @@ type decoder interface {
}

func newCodec() encoderDecoder {
return &codecImpl{
varIntPool: sync.Pool{
New: func() interface{} {
return make([]byte, binary.MaxVarintLen64)
},
},
}
return &codecImpl{}
}

// Note that bytes.Buffer.Write always returns nil, so we
// can ignore its return values in [codecImpl] methods.
type codecImpl struct {
// Invariant: Every byte slice returned by [varIntPool] has
// length [binary.MaxVarintLen64].
varIntPool sync.Pool
}
type codecImpl struct{}

func (c *codecImpl) childSize(index byte, childEntry *child) int {
// * index
Expand Down Expand Up @@ -285,11 +274,10 @@ func (*codecImpl) decodeUint(src *bytes.Reader) (uint64, error) {
return val64, nil
}

func (c *codecImpl) encodeUint(dst *bytes.Buffer, value uint64) {
buf := c.varIntPool.Get().([]byte)
size := binary.PutUvarint(buf, value)
func (*codecImpl) encodeUint(dst *bytes.Buffer, value uint64) {
var buf [binary.MaxVarintLen64]byte
size := binary.PutUvarint(buf[:], value)
_, _ = dst.Write(buf[:size])
c.varIntPool.Put(buf)
}

func (c *codecImpl) encodeMaybeByteSlice(dst *bytes.Buffer, maybeValue maybe.Maybe[[]byte]) {
Expand Down
17 changes: 17 additions & 0 deletions x/merkledb/codec_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"io"
"math"
"math/rand"
"strconv"
"testing"

"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -266,3 +267,19 @@ func TestUintSize(t *testing.T) {
require.Equal(t, expectedSize, actualSize, power)
}
}

func Benchmark_EncodeUint(b *testing.B) {
c := codec.(*codecImpl)

var dst bytes.Buffer
dst.Grow(binary.MaxVarintLen64)

for _, v := range []uint64{0, 1, 2, 32, 1024, 32768} {
b.Run(strconv.FormatUint(v, 10), func(b *testing.B) {
for i := 0; i < b.N; i++ {
c.encodeUint(&dst, v)
dst.Reset()
}
})
}
}

0 comments on commit 2a0bd08

Please sign in to comment.