Skip to content

Commit 62e5235

Browse files
committed
internal: use a sync.Pool of msgpack.Decoder
The change helps to avoid 2 allocations per a response decoding. You could check the change with the command: $ go test -v . -bench . -run fff -benchmem
1 parent c0a8ad3 commit 62e5235

File tree

8 files changed

+62
-34
lines changed

8 files changed

+62
-34
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@ Versioning](http://semver.org/spec/v2.0.0.html) except to the first release.
1010

1111
### Added
1212

13+
- A usage of sync.Pool of msgpack.Decoder saves 2 object allocations per
14+
a response decoding.
15+
1316
### Changed
1417

1518
- Connect() now retry the connection if a failure occurs and opts.Reconnect > 0.

box_error.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,9 @@ func (e *BoxError) UnmarshalMsgpack(b []byte) error {
278278
}
279279

280280
buf := bytes.NewBuffer(b)
281-
dec := msgpack.NewDecoder(buf)
281+
282+
dec := getDecoder(buf)
283+
defer putDecoder(dec)
282284

283285
if val, err := decodeBoxError(dec); err != nil {
284286
return err

connection.go

+3-1
Original file line numberDiff line numberDiff line change
@@ -803,7 +803,9 @@ func (conn *Connection) writer(w writeFlusher, c Conn) {
803803
func readWatchEvent(reader io.Reader) (connWatchEvent, error) {
804804
keyExist := false
805805
event := connWatchEvent{}
806-
d := msgpack.NewDecoder(reader)
806+
807+
d := getDecoder(reader)
808+
defer putDecoder(d)
807809

808810
l, err := d.DecodeMapLen()
809811
if err != nil {

decoder.go

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
package tarantool
2+
3+
import (
4+
"io"
5+
"sync"
6+
7+
"github.com/vmihailenco/msgpack/v5"
8+
)
9+
10+
func untypedMapDecoder(dec *msgpack.Decoder) (interface{}, error) {
11+
return dec.DecodeUntypedMap()
12+
}
13+
14+
var decPool = sync.Pool{
15+
New: func() interface{} {
16+
d := msgpack.NewDecoder(nil)
17+
18+
return d
19+
},
20+
}
21+
22+
func getDecoder(r io.Reader) *msgpack.Decoder {
23+
d := decPool.Get().(*msgpack.Decoder)
24+
25+
d.Reset(r)
26+
d.SetMapDecoder(untypedMapDecoder)
27+
28+
return d
29+
}
30+
31+
func putDecoder(dec *msgpack.Decoder) {
32+
decPool.Put(dec)
33+
}

dial.go

+5-1
Original file line numberDiff line numberDiff line change
@@ -547,7 +547,11 @@ func readResponse(r io.Reader, req Request) (Response, error) {
547547
}
548548

549549
buf := smallBuf{b: respBytes}
550-
header, _, err := decodeHeader(msgpack.NewDecoder(&smallBuf{}), &buf)
550+
551+
d := getDecoder(&buf)
552+
defer putDecoder(d)
553+
554+
header, _, err := decodeHeader(d, &buf)
551555
if err != nil {
552556
return nil, fmt.Errorf("decode response header error: %w", err)
553557
}

go.mod

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ require (
77
github.com/shopspring/decimal v1.3.1
88
github.com/stretchr/testify v1.9.0
99
github.com/tarantool/go-iproto v1.1.0
10-
github.com/vmihailenco/msgpack/v5 v5.3.5
10+
github.com/vmihailenco/msgpack/v5 v5.4.1
1111
)
1212

1313
require (

go.sum

+2-6
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
21
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
32
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
43
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
76
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
87
github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
98
github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
10-
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
11-
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
129
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
1310
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
1411
github.com/tarantool/go-iproto v1.1.0 h1:HULVOIHsiehI+FnHfM7wMDntuzUddO09DKqu2WnFQ5A=
1512
github.com/tarantool/go-iproto v1.1.0/go.mod h1:LNCtdyZxojUed8SbOiYHoc3v9NvaZTB7p96hUySMlIo=
16-
github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9znI5mJU=
17-
github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc=
13+
github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8=
14+
github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok=
1815
github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g=
1916
github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds=
2017
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2118
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
22-
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
2319
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
2420
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

response.go

+12-24
Original file line numberDiff line numberDiff line change
@@ -329,10 +329,8 @@ func (resp *baseResponse) Decode() ([]interface{}, error) {
329329
var l int
330330
info := &decodeInfo{}
331331

332-
d := msgpack.NewDecoder(&resp.buf)
333-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
334-
return dec.DecodeUntypedMap()
335-
})
332+
d := getDecoder(&resp.buf)
333+
defer putDecoder(d)
336334

337335
if l, err = d.DecodeMapLen(); err != nil {
338336
resp.err = err
@@ -384,10 +382,8 @@ func (resp *SelectResponse) Decode() ([]interface{}, error) {
384382
var l int
385383
info := &decodeInfo{}
386384

387-
d := msgpack.NewDecoder(&resp.buf)
388-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
389-
return dec.DecodeUntypedMap()
390-
})
385+
d := getDecoder(&resp.buf)
386+
defer putDecoder(d)
391387

392388
if l, err = d.DecodeMapLen(); err != nil {
393389
resp.err = err
@@ -447,10 +443,8 @@ func (resp *ExecuteResponse) Decode() ([]interface{}, error) {
447443
var l int
448444
info := &decodeInfo{}
449445

450-
d := msgpack.NewDecoder(&resp.buf)
451-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
452-
return dec.DecodeUntypedMap()
453-
})
446+
d := getDecoder(&resp.buf)
447+
defer putDecoder(d)
454448

455449
if l, err = d.DecodeMapLen(); err != nil {
456450
resp.err = err
@@ -535,10 +529,8 @@ func (resp *baseResponse) DecodeTyped(res interface{}) error {
535529
info := &decodeInfo{}
536530
var l int
537531

538-
d := msgpack.NewDecoder(&resp.buf)
539-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
540-
return dec.DecodeUntypedMap()
541-
})
532+
d := getDecoder(&resp.buf)
533+
defer putDecoder(d)
542534

543535
if l, err = d.DecodeMapLen(); err != nil {
544536
return err
@@ -576,10 +568,8 @@ func (resp *SelectResponse) DecodeTyped(res interface{}) error {
576568
info := &decodeInfo{}
577569
var l int
578570

579-
d := msgpack.NewDecoder(&resp.buf)
580-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
581-
return dec.DecodeUntypedMap()
582-
})
571+
d := getDecoder(&resp.buf)
572+
defer putDecoder(d)
583573

584574
if l, err = d.DecodeMapLen(); err != nil {
585575
return err
@@ -624,10 +614,8 @@ func (resp *ExecuteResponse) DecodeTyped(res interface{}) error {
624614
info := &decodeInfo{}
625615
var l int
626616

627-
d := msgpack.NewDecoder(&resp.buf)
628-
d.SetMapDecoder(func(dec *msgpack.Decoder) (interface{}, error) {
629-
return dec.DecodeUntypedMap()
630-
})
617+
d := getDecoder(&resp.buf)
618+
defer putDecoder(d)
631619

632620
if l, err = d.DecodeMapLen(); err != nil {
633621
return err

0 commit comments

Comments
 (0)