Skip to content

Commit 8b89d6b

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 Bench -run f -benchmem
1 parent c0a8ad3 commit 8b89d6b

File tree

6 files changed

+59
-27
lines changed

6 files changed

+59
-27
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
}

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)