Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

No allocations on EncodeTime, run benchmarks #224

Merged
merged 1 commit into from
Mar 27, 2019

Conversation

smira
Copy link
Contributor

@smira smira commented Mar 26, 2019

Use per-instance lazily-allocated buffer to avoid allocations
in EncodeTime. We can't use use e.buf, as it's used to
encode extLen, and it's smaller than required (9 bytes).
Using buffer on stack doesn't work, as Go doesn't have
a way to figure out if e.write(b) escapes or not, so it thinks
it always escapes.

Run benchmarks for make (and in Travis CI), and fix benchmark
which was failing probably due to some changes in the codebase.

Benchmark, before:

BenchmarkTime-12    	20000000	        94.0 ns/op	       8 B/op	       1 allocs/op

after:

BenchmarkTime-12    	20000000	        76.7 ns/op	       0 B/op	       0 allocs/op

smira added a commit to smira/zap-msgpack-encoder that referenced this pull request Mar 26, 2019
We anyway need to cache in sync.Pool instances of msgpack Encoder
object, and this object is bound to Writer instance (Buffer in our
case). There's no way to reset encoder to use different buffer, and
there's no way to avoid buffer from being recycled if returned, so it's
easier to use bytes.Buffer which has necessary APIs to avoid extra
allocations (see uber-go/zap#691).

The only allocation left in the benchmark is from msgpack's EncodeTime
function, PR is submitted for it: vmihailenco/msgpack#224
encode.go Outdated
@@ -53,6 +53,8 @@ type Encoder struct {
w writer
buf []byte

tbuf []byte
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please group this with other buf var and rename to timeBuf. Also having a comment why we need another buffer ("We can't use use e.buf, as it's used to encode extLen") will help future readers a lot.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, updated

Use per-instance lazily-allocated buffer to avoid allocations
in `EncodeTime`. We can't use use `e.buf`, as it's used to
encode extLen, and it's smaller than required (9 bytes).
Using buffer on stack doesn't work, as Go doesn't have
a way to figure out if `e.write(b)` escapes or not, so it thinks
it always escapes.

Run benchmarks for `make` (and in Travis CI), and fix benchmark
which was failing probably due to some changes in the codebase.

Benchmark, before:

```
BenchmarkTime-12    	20000000	        94.0 ns/op	       8 B/op	       1 allocs/op
```

after:

```
BenchmarkTime-12    	20000000	        76.7 ns/op	       0 B/op	       0 allocs/op
```
@vmihailenco
Copy link
Owner

Thank you!

@vmihailenco vmihailenco merged commit c2fc210 into vmihailenco:master Mar 27, 2019
@smira
Copy link
Contributor Author

smira commented Mar 27, 2019

would you mind tagging new release with this commit please?

@vmihailenco
Copy link
Owner

Tagged v4.0.4

smira added a commit to smira/zap-msgpack-encoder that referenced this pull request Mar 27, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants