Closed stevejgordon closed 5 years ago
Potential basis of a sample. Ignore the TPL Dataflow bits but this shoulds creating a policy which calls the appropriate object reset method, called when returning an object to the pool.
Some basic notes on this:
The ObjectPool
is a piece of infrastructure that supports keeping a group of objects in memory for reuse rather than allowing the objects to be garbage collected.
You might want to use the object pool if the objects that are being managed are:
As an example, the framework uses the object pool in some places to reuse StringBuilder
instances. StringBuilder
allocates and manages its own buffers to hold character data when used. Since ASP.NET Core regularly uses StringBuilder
to implement features, it makes sense for us to reuse them.
Every decision has performance tradeoffs, and you should only use a technique like pooling after collecting performance data about realistic scenarios for your application or library. In particular, getting an object from the pool will usually be slower then allocating an object unless the initialization or allocation cost of that kind of object is high. Additionally, by using the pool, you will prevent objects managed by the pool from being de-allocated until you de-allocate the pool.
WARNING: The ObjectPool doesn't implement IDisposable
. We don't recommend using it with types that need disposal.
NOTE: The ObjectPool doesn't place a limit on the number of objects that it will allocate, it places a limit on the number of object it will retain.
ObjectPool<T>
- the basic object pool abstraction. This is what your code should use to get and return objects.
PooledObjectPolicy<T>
- implement this to customize how an object is created and how it is reset when returned to the pool. This can be passed into an object pool that you construct directly.... OR
ObjectPoolProvider<T>
acts as a factory for creating object pools.
You can wire these up however you like - either by instantiating a pool yourself, or by registering a pool in DI as an instance, or registering the ObjectPoolProvider<>
in DI and using it as a factory.
Call ObjectPool<T>.Get()
to get an object and ObjectPool<T>.Return
to return it. There's no requirement that you return every object - if you don't return an object, then it will be garbage collected.
@stevejgordon can you write a simple sample app that uses ObjectPool
? I can get this documented. Should it go in the Performance node?
@Rick-Anderson I can try to throw a sample together. I spoke to @rynowak at NDC and he had a good sample concept we could show.
We have the need for an object pool for a non thread-safe object in ML.NET: The PredictionEngine object. I'm going to create a sample implementing an object pool of PredictionEngine objects. I'll reference it back here so you guys can take a look to it, too.
@stevejgordon a sample would be great.
Here's an example. However, it is related to ML.NET. For a tutorial just focusing on ObjectPooling, a simple pooled object with dumb data might be easier to understand? In any case, here it is: https://github.com/CESARDELATORRE/MLNET-Approaches/tree/master/Multi-Project-Solution/SampleRegression.Common/MLModelScorerObjPool
@Rick-Anderson Sorry for the delay (again)! I have a basic example which I've now pushed up to https://github.com/stevejgordon/ObjectPoolSample. It's quite a trivial example but I think shows the keys points and hopefully best practice. It may need a little work to tidy it up as it was a WIP for a blog post I was working on. Perhaps @rynowak can review and ensure it looks good also?
@CESARDELATORRE is this the right sample? https://github.com/CESARDELATORRE/MLNET-Approaches/tree/master/Multi-Project-Solution-ObjPooling
ObjectPool exists in Microsoft.Extensions.ObjectPool but does not appear to be documented in terms of when and how it should be used.
It would be good to provide guidance and when using ObjectPool may be appropriate.
Describe the use of classes deriving from PooledObjectPolicy, the creation of a pool from the provider, getting and returning items to the pool.
FYI - @rynowak and @scottaddie