Why you should like sync.Pool?

By Mnwa Mnowich

Because it’s fast . x4982 reducing memory usage and repository with benchmarks below.

Comparing pool performance. Less than better.

The garbage collector runs at regular intervals. In case your code constantly allocates memory in some data structures and then frees them, this requires constant work of the collector, more memory and cpu usage for allocating resources on init structs.

The comments on sync/pool.go  say that:
A Pool is a set of temporary objects that may be individually saved and retrieved.
A Pool is safe for use by multiple goroutines simultaneously.

sync.Pool allows us to reuse memory without allocate.

Also if you are have http server which wait post requests with json body and it must decode to the structure you can use sync.Pool to save memory and reduce server response time.

sync.Pool construction is simple:

var bufferPool = sync.Pool{
New: func() interface{} {
return new(bytes.Buffer)

Now you have pool which will be create and new buffers. You can get you first buffer here:

buffer := bufferPool.Get().(*bytes.Buffer)

Method get will return already existing *bytes.Buffer in the pool and if it’s not will call method New which init new *bytes.Buffer

But after buffer usage you must reset and put it to pool back:

// That code tried to json encode structure
BenchmarkReadStreamWithPool-8        5000000        384 ns/op        0 B/op        0 allocs/op
BenchmarkReadStreamWithoutPool-8 3000000 554 ns/op 160 B/op 2 allocs/op

We have 44% performance boost and save very-very much memory (160B/ops vs 0B/ops)

BenchmarkWriteBufioWithPool-8       10000000        123 ns/op      128 B/op        2 allocs/op
BenchmarkWriteBufioWithoutPool-8 2000000 651 ns/op 4288 B/op 4 allocs/op

We have x5 performance boost and x32 reduced memory usage

BenchmarkJsonDecodeWithPool-8        1000000       1729 ns/op     1128 B/op        8 allocs/op
BenchmarkJsonDecodeWithoutPool-8 1000000 1751 ns/op 1160 B/op 9 allocs/op

We have 1% performance boost because json decode is too hard operation and we cannot see normal boost by the reusing structures.

BenchmarkWriteGzipWithPool-8          500000       2339 ns/op      162 B/op        2 allocs/op
BenchmarkWriteGzipWithoutPool-8 10000 105288 ns/op 807088 B/op 16 allocs/op

Stop, what? x45 performance boost and x4982 reduced memory usage

Always use sync.Pool when you can! It really saves memory and increase performance of you application.

Github repository with benchmarks here.