diff options
author | Marius van der Wijden <m.vanderwijden@live.de> | 2019-02-25 18:34:08 +0800 |
---|---|---|
committer | Péter Szilágyi <peterke@gmail.com> | 2019-02-25 18:34:08 +0800 |
commit | 7d881e45bdaad3cf1a301c7523a07026a479fd04 (patch) | |
tree | 637cd5891967904f0fba84d65e9ccd0ff43d9706 /rlp/decode.go | |
parent | 872370e3bc3c753937784e33e32d499ec277ab5f (diff) | |
download | go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.gz go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.bz2 go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.lz go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.xz go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.tar.zst go-tangerine-7d881e45bdaad3cf1a301c7523a07026a479fd04.zip |
rlp: added pooling of streams using sync (#19044)
Prevents reallocation, improves performance
Diffstat (limited to 'rlp/decode.go')
-rw-r--r-- | rlp/decode.go | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/rlp/decode.go b/rlp/decode.go index dbbe59959..e638c01ea 100644 --- a/rlp/decode.go +++ b/rlp/decode.go @@ -26,6 +26,7 @@ import ( "math/big" "reflect" "strings" + "sync" ) var ( @@ -48,6 +49,10 @@ var ( errUintOverflow = errors.New("rlp: uint overflow") errNoPointer = errors.New("rlp: interface given to Decode must be a pointer") errDecodeIntoNil = errors.New("rlp: pointer given to Decode must not be nil") + + streamPool = sync.Pool{ + New: func() interface{} { return new(Stream) }, + } ) // Decoder is implemented by types that require custom RLP @@ -126,17 +131,24 @@ type Decoder interface { // // NewStream(r, limit).Decode(val) func Decode(r io.Reader, val interface{}) error { - // TODO: this could use a Stream from a pool. - return NewStream(r, 0).Decode(val) + stream := streamPool.Get().(*Stream) + defer streamPool.Put(stream) + + stream.Reset(r, 0) + return stream.Decode(val) } // DecodeBytes parses RLP data from b into val. // Please see the documentation of Decode for the decoding rules. // The input must contain exactly one value and no trailing data. func DecodeBytes(b []byte, val interface{}) error { - // TODO: this could use a Stream from a pool. r := bytes.NewReader(b) - if err := NewStream(r, uint64(len(b))).Decode(val); err != nil { + + stream := streamPool.Get().(*Stream) + defer streamPool.Put(stream) + + stream.Reset(r, uint64(len(b))) + if err := stream.Decode(val); err != nil { return err } if r.Len() > 0 { @@ -853,6 +865,7 @@ func (s *Stream) Reset(r io.Reader, inputLimit uint64) { if s.uintbuf == nil { s.uintbuf = make([]byte, 8) } + s.byteval = 0 } // Kind returns the kind and size of the next value in the |