You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I'm proposing to extend sync.Pool to allow Put() and Get() of multiple objects in a single call. This proposal could be implemented by adding a few new methods:
// PutFromSlice adds all entries from xs to the pool.//// It behaves like the following code:// for _, x := range xs {// pool.Put(x)// }func (p*Pool[T]) PutFromSlice(xs []*T)
funcPoolPutFromSlice[Tany](p*Pool, xs []*T) // workaround for no type params on Pool// FillSlice selects arbitrary items from the Pool, removes them from the Pool,// and places them into xs.//// If there is not enough items to fill the slice, the remaining part of the// slice is filled with nils. But if p.New is non-nil, the remaining part is// filled with the results of calling p.New repeatedly.//// It behaves like the following code:// for i := range xs {// if x := pool.Get(); x != nil {// xs[i] = x.(*T) // panic if conversion fails// } else {// xs[i] = nil// }// }func (p*Pool[T]) FillSlice(xs []*T)
funcPoolFillSlice[Tany](p*Pool, xs []*T) // workaround for no type params on Pool
Without type params the ergonomics of the API would be beyond disgusting. Without it the API would need to take in a slice of []any requiring the users to convert their slices to that type. Or perhaps it would require something equally abhorrent.
The motivation is performance. It's starting to become a pattern in my hot path to have a slice of objects to free or to need. Right now I'm just calling Get/Put in a loop to fill/release such slices. One unfortunately common detail that I have going on is that one goroutine does the Gets and after some processing it's some another goroutine that Puts those objects back to the pool. When under load this ends up meaning that the goroutine doing the Gets mostly ends up taking the slow path of Get(). Get() of a slice of objects surely allows new optimizations in the slow path considering how complex of a data structure Pool is.
The text was updated successfully, but these errors were encountered:
@seankhliao no comment on the merit or approach of this proposal, but I believe it is unrelated to #47657 and should be re-opened.
This proposal (or something like it) would enable batch Get and Put for different numbers of items. Eg, transaction A might Get/Put 3 widgets and transaction B might Get/Put 10 widgets.
That particular issue seems like a good home for this proposal considering that it seems to be a small redesign of the API anyways. I commented my proposal there.
I'm proposing to extend sync.Pool to allow Put() and Get() of multiple objects in a single call. This proposal could be implemented by adding a few new methods:
Without type params the ergonomics of the API would be beyond disgusting. Without it the API would need to take in a slice of
[]any
requiring the users to convert their slices to that type. Or perhaps it would require something equally abhorrent.The motivation is performance. It's starting to become a pattern in my hot path to have a slice of objects to free or to need. Right now I'm just calling Get/Put in a loop to fill/release such slices. One unfortunately common detail that I have going on is that one goroutine does the Gets and after some processing it's some another goroutine that Puts those objects back to the pool. When under load this ends up meaning that the goroutine doing the Gets mostly ends up taking the slow path of Get(). Get() of a slice of objects surely allows new optimizations in the slow path considering how complex of a data structure Pool is.
The text was updated successfully, but these errors were encountered: