leaky buffer with channel or sync.Pool

517 views
Skip to first unread message

Jérôme LAFORGE

unread,
Oct 18, 2015, 10:54:15 AM10/18/15
to golang-nuts
Hello,

For implementing leaky buffer, you can do it :
- with channel (as descibe into https://golang.org/doc/effective_go.html#leaky_buffer)
- or with sync.Pool.

Do you know if there is some difference on performance perspective (or on others aspects) on this both choices?

Thx in adv.
Regard

Dave Cheney

unread,
Oct 18, 2015, 4:47:46 PM10/18/15
to golang-nuts
The latter is faster, but has the unfortunate requirement to smuggle everything via an interface{}

Matt Silverlock

unread,
Oct 18, 2015, 11:28:15 PM10/18/15
to golang-nuts
There's also a discussion here about sync.Pool - https://groups.google.com/forum/#!topic/golang-nuts/n_By5xPzDho/discussion

The most important thing to remember is that you MUST explicitly zero objects you return (or get; either way) from the pool. Writing your own convenience methods around the Get/Put methods will help to enforce that, as well as the necessary type assertions.

Klaus Post's post on gzip writer pools also provides some useful example code around using sync.Pool - https://blog.klauspost.com/gzip-performance-for-go-webservers/ - and I wrote an article not long ago on the channel-based approach: http://elithrar.github.io/article/using-buffer-pools-with-go/ 

Jérôme LAFORGE

unread,
Oct 19, 2015, 4:04:16 AM10/19/15
to golang-nuts
Thx you both for your replies.

Just for sum up all stuff on sync.Pool, can I consider as true the following:
- sync.Pool is faster than channel due some improvement when we use multi-processor machine
- with sync.Pool, you can't defined upper limit (unlike channel)
- with sync.Pool, buffer can be garbage collected even if there are stored into sync.Pool (kind of java.lang.ref.WeakReference)

Tamás Gulácsi

unread,
Oct 19, 2015, 4:52:01 AM10/19/15
to golang-nuts
2015. október 19., hétfő 10:04:16 UTC+2 időpontban Jérôme LAFORGE a következőt írta:
Thx you both for your replies.

Just for sum up all stuff on sync.Pool, can I consider as true the following:
- sync.Pool is faster than channel due some improvement when we use multi-processor machine
- with sync.Pool, you can't defined upper limit (unlike channel)
- with sync.Pool, buffer can be garbage collected even if there are stored into sync.Pool (kind of java.lang.ref.WeakReference)

AFAIK yes.

Leaky buffer provides better control about availability of some heavy resource, with limit,
sync.Pool is a faster temporary store for some not too cheap resource, without limit. (Although some implicit limit exists: when the GC kicks in (the memory grows to 2x of its previous size, for example because the items in sync.Pool occupies a lot), it will empty the sync.Pool).
 

Dave Cheney

unread,
Oct 19, 2015, 5:25:45 AM10/19/15
to golang-nuts
- with sync.Pool, buffer can be garbage collected even if there are stored into sync.Pool (kind of java.lang.ref.WeakReference)


The pool will be cleared during garbage collection, it is not a cache. This also mitigates your previous point, putting too many things into a pool will cause a garbage collection cycle, which will empty the pool.

Jérôme LAFORGE

unread,
Oct 20, 2015, 3:29:56 AM10/20/15
to golang-nuts
Thx you all for your replies. As previously writen here, what awesome community you are :)


> The pool will be cleared during garbage collection, it is not a cache. This also mitigates your previous point, putting too many things into a pool will cause a garbage collection cycle, which will empty the pool.
If I understand correctly, when the garbage collection is running, it will remove all elements stored into sync.Pool regardless of the size of this sync.Pool or regardless of when this element has been last time used.

Plz correct me, if I am wrong.
With this kind of behavior, when the gc is launched (because there is some memory allocation elsewhere into the program) and for one specific loading (e.g x QPS) it is likely that all needed elements (for managing this specific QPS) will be out of  sync.Pool, and so they won't be removed by gc (because there are actually used).
The sync.Pool will find automatically the correct size of elements regardless the loading, and gc will be remove all unnecessary elements (e.g. previously created during a last burst)
For my point of view, this seems to be a very elegant way to find the optimal size of sync.Pool unlike the channel where you have to tune its size by rule of thumb or by more scientific approach.

Dave Cheney

unread,
Oct 20, 2015, 3:53:32 AM10/20/15
to golang-nuts
Here is some background reading, http://dominik.honnef.co/go-tip/2014-01-10/

The take away is, sync.Pool is not a cache, a confirming implementation can throw away everything it is given.

Reply all
Reply to author
Forward
0 new messages