Sync pool old data

274 views
Skip to first unread message

XXX ZZZ

unread,
Oct 11, 2017, 3:50:15 PM10/11/17
to golang-nuts
Hello,

So I'm starting to play with sync pool on a program that needs to allocate a ton of short lived objects per server request. Performance seems to be better when using sync pool however I've noticed that upon releasing the object and then retrieving it again, will produce a "new object" with "old request data". The solution for this would be to reset the object values/structs to 0, however I feel this will kinda defeat the purpose of using sync pool. After all, we will always be creating new objects.

Given that sync pool is used to avoid overhead when creating a lot of elements, i would assume that I'm missing something here. Could anyone please shred some light on this?

package main

import(
"sync"
"fmt"
)
type struct1 struct{
  obj1  struct2
  obj2  struct3
}

type struct2 struct{
   a string
}

type struct3 struct{
  a string
}


func AcquireStruct1() *struct1 {
    return struct1pool.Get().(*struct1)
}
func ReleaseStruct1(u *struct1 ) {
    //u.Reset()
    struct1pool.Put(u)
}
var struct1pool= &sync.Pool{
    New: func() interface{} {
        a:=&struct1{}
        return a
    },
}

func main(){
  a:=AcquireStruct1()
  a.obj1.a="a"
  a.obj2.a="a"
  ReleaseStruct1(a)

  a=AcquireStruct1()
  fmt.Printf("%+v", a) // this outputs the data assigned to the first object
}
}

https://play.golang.org/p/JHHdwG1aqc

Thanks in advance.

Ian Lance Taylor

unread,
Oct 11, 2017, 4:03:30 PM10/11/17
to XXX ZZZ, golang-nuts
On Wed, Oct 11, 2017 at 12:50 PM, XXX ZZZ <emarti...@gmail.com> wrote:
>
> So I'm starting to play with sync pool on a program that needs to allocate a
> ton of short lived objects per server request. Performance seems to be
> better when using sync pool however I've noticed that upon releasing the
> object and then retrieving it again, will produce a "new object" with "old
> request data". The solution for this would be to reset the object
> values/structs to 0, however I feel this will kinda defeat the purpose of
> using sync pool. After all, we will always be creating new objects.

Yes, if you use sync.Pool, you must re-initialize any object you get
from the pool, or you must restore any object you store in the pool
back to the initial state. That is unavoidable.


> Given that sync pool is used to avoid overhead when creating a lot of
> elements, i would assume that I'm missing something here. Could anyone
> please shred some light on this?

That's not quite what sync.Pool is for. sync.Pool is useful for
objects whose lifetime is bounded by a single operation, when there
can be parallel operations, when the number of parallel operations
varies significantly. In such a case sync.Pool provides a cache that
lets you decrease allocation cost. It's just one technique for
decreasing allocation cost, and there are several others. Most
obviously, if the number of parallel operations does not vary
significantly, a freelist is a simpler and more effective technique.

Ian

Bryan Mills

unread,
Oct 12, 2017, 11:38:19 AM10/12/17
to golang-nuts
On Wednesday, October 11, 2017 at 4:03:30 PM UTC-4, Ian Lance Taylor wrote:
if the number of parallel operations does not vary
significantly, a freelist is a simpler and more effective technique.

A freelist might be simpler, but it isn't necessarily more effective. sync.Pool combines two (non-orthogonal) properties: thread-local allocation and weak references.

If the number of operations does not vary, the weak references don't matter much, but the thread-local allocation might. If many operations occur in parallel on a system with many CPU cores, a freelist can suffer from significant cache contention, whereas a sync.Pool generally will not. (See also https://golang.org/issue/18802.)

That said, Go's allocator is fairly thread-local to begin with, so if you're explicitly zeroing out the objects before reusing them anyway, sync.Pool should provide very little benefit over simply allocating a new object for each operation. (That is especially true when the objects are small, and thus more likely to be satisfiable out of memory the thread has already obtained.)

Reply all
Reply to author
Forward
0 new messages