diff --git a/CHANGELOG.md b/CHANGELOG.md index 00049a9c..3b87725d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,9 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release. ### Added +- A usage of sync.Pool of msgpack.Decoder saves 2 object allocations per + a response decoding. + ### Changed - Connect() now retry the connection if a failure occurs and opts.Reconnect > 0. diff --git a/box_error.go b/box_error.go index 3d76a942..59bfb4a0 100644 --- a/box_error.go +++ b/box_error.go @@ -278,7 +278,9 @@ func (e *BoxError) UnmarshalMsgpack(b []byte) error { } buf := bytes.NewBuffer(b) - dec := msgpack.NewDecoder(buf) + + dec := getDecoder(buf) + defer putDecoder(dec) if val, err := decodeBoxError(dec); err != nil { return err diff --git a/connection.go b/connection.go index 97f9dbbc..8c8552e6 100644 --- a/connection.go +++ b/connection.go @@ -803,7 +803,9 @@ func (conn *Connection) writer(w writeFlusher, c Conn) { func readWatchEvent(reader io.Reader) (connWatchEvent, error) { keyExist := false event := connWatchEvent{} - d := msgpack.NewDecoder(reader) + + d := getDecoder(reader) + defer putDecoder(d) l, err := d.DecodeMapLen() if err != nil { diff --git a/decoder.go b/decoder.go new file mode 100644 index 00000000..d1c68288 --- /dev/null +++ b/decoder.go @@ -0,0 +1,24 @@ +package tarantool + +import ( + "io" + + "github.com/vmihailenco/msgpack/v5" +) + +func untypedMapDecoder(dec *msgpack.Decoder) (interface{}, error) { + return dec.DecodeUntypedMap() +} + +func getDecoder(r io.Reader) *msgpack.Decoder { + d := msgpack.GetDecoder() + + d.Reset(r) + d.SetMapDecoder(untypedMapDecoder) + + return d +} + +func putDecoder(dec *msgpack.Decoder) { + msgpack.PutDecoder(dec) +} diff --git a/dial.go b/dial.go index ac191903..d0acf69c 100644 --- a/dial.go +++ b/dial.go @@ -547,7 +547,11 @@ func readResponse(r io.Reader, req Request) (Response, error) { } buf := smallBuf{b: respBytes} - header, _, err := decodeHeader(msgpack.NewDecoder(&smallBuf{}), &buf) + + d := getDecoder(&buf) + defer putDecoder(d) + + header, _, err := decodeHeader(d, &buf) if err != nil { return nil, fmt.Errorf("decode response header error: %w", err) } diff --git a/go.mod b/go.mod index 237d390c..5b44eb1c 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/shopspring/decimal v1.3.1 github.com/stretchr/testify v1.9.0 github.com/tarantool/go-iproto v1.1.0 - github.com/vmihailenco/msgpack/v5 v5.3.5 + github.com/vmihailenco/msgpack/v5 v5.4.1 ) require ( diff --git a/go.sum b/go.sum index a66c68ef..099647b8 100644 --- a/go.sum +++ b/go.sum @@ -1,4 +1,3 @@ -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= @@ -7,18 +6,15 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= github.com/tarantool/go-iproto v1.1.0 h1:HULVOIHsiehI+FnHfM7wMDntuzUddO09DKqu2WnFQ5A= github.com/tarantool/go-iproto v1.1.0/go.mod h1:LNCtdyZxojUed8SbOiYHoc3v9NvaZTB7p96hUySMlIo= -github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU= -github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= +github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= +github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/response.go b/response.go index 90a02a1c..36aad66a 100644 --- a/response.go +++ b/response.go @@ -329,10 +329,8 @@ func (resp *baseResponse) Decode() ([]interface{}, error) { var l int info := &decodeInfo{} - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { resp.err = err @@ -384,10 +382,8 @@ func (resp *SelectResponse) Decode() ([]interface{}, error) { var l int info := &decodeInfo{} - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { resp.err = err @@ -447,10 +443,8 @@ func (resp *ExecuteResponse) Decode() ([]interface{}, error) { var l int info := &decodeInfo{} - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { resp.err = err @@ -535,10 +529,8 @@ func (resp *baseResponse) DecodeTyped(res interface{}) error { info := &decodeInfo{} var l int - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { return err @@ -576,10 +568,8 @@ func (resp *SelectResponse) DecodeTyped(res interface{}) error { info := &decodeInfo{} var l int - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { return err @@ -624,10 +614,8 @@ func (resp *ExecuteResponse) DecodeTyped(res interface{}) error { info := &decodeInfo{} var l int - d := msgpack.NewDecoder(&resp.buf) - d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) { - return dec.DecodeUntypedMap() - }) + d := getDecoder(&resp.buf) + defer putDecoder(d) if l, err = d.DecodeMapLen(); err != nil { return err