While writing eXtremecode's business layer, I found some performance related issues when creating a large number of business objects.
Each business object contains some heavy objects which require comparatively larger amount of system memory. Firstly I was creating these objects on each creation of business object, later I realized that these objects should be shared by related business objects, but that was not the solution as business objects were being created in different threads. Finally I decided to make a pool of similar objects so each thread could request pooled objects and could use them independently.
Pooling Source Code
/** Copyright (c) 2010, Sheikh Abdul Wahid Ahmed Details @ http://extremecodeworld.codeplex.com/license **/ using System; using System.Collections.Generic; using System.Text; using System.Collections; using System.Threading; namespace EXtremecode.Common { public interface IPooledObject { ObjectPool Pool { get; set; } } public class ObjectPool { private Stack<IPooledObject> pool = new Stack<IPooledObject>(); private int poolSize; private int numberOfPooledObjectsCreated = 0; private int timeOut = 15000; // in millisecond private Func<IPooledObject> CreateObject; private AutoResetEvent autoReset = new AutoResetEvent(false); private string poolName = string.Empty; public ObjectPool(Func<IPooledObject> CreateObject) : this("UnKnown", CreateObject, 10, 15000) {} public ObjectPool(string poolName, Func<IPooledObject> CreateObject) : this(poolName, CreateObject, 10, 15000) { } public ObjectPool(Func<IPooledObject> CreateObject , int timeOut) : this("UnKnown", CreateObject, 10 ,timeOut) { } public ObjectPool(string poolName, Func<IPooledObject> CreateObject , int timeOut) : this(poolName, CreateObject, 10, timeOut) { } public ObjectPool(string poolName,Func<IPooledObject> CreateObject , int poolSize, int timeOut) { this.CreateObject = CreateObject; this.poolSize = poolSize; this.poolName = poolName; this.timeOut = timeOut; } public IPooledObject GetObject() { while (true) { lock (pool) { if (pool.Count > 0) { //get object from the pool. Console.WriteLine("[{0}] PooledObject Poped (Opened Objects [{1}])" , poolName ,numberOfPooledObjectsCreated - pool.Count); return pool.Pop(); } else { if (numberOfPooledObjectsCreated < poolSize) { //numbers of pooled object has not crossed the limit yet //so create new object and return IPooledObject pooledObject = CreateObject(); if (pooledObject != null) { numberOfPooledObjectsCreated++; pooledObject.Pool = this; //add self reference //which will be used to get the object back into pool again. } Console.WriteLine("[{0}] PooledObject Created (Opened Objects [{1}])" , poolName , numberOfPooledObjectsCreated - pool.Count); return pooledObject; } } Console.WriteLine("[{0}] Waiting for PooledObject", poolName); bool timeOutOccured = !autoReset.WaitOne(timeOut); if (timeOutOccured) { throw new Exception( string.Format("object request from the pool '{0}' has been timeout" , poolName)); } } } } [System.Runtime.CompilerServices.MethodImpl (System.Runtime.CompilerServices.MethodImplOptions.Synchronized)] public void ReleaseObject(IPooledObject pooledObject) { pool.Push(pooledObject); autoReset.Set(); Console.WriteLine("[{0}] PooledObject Pushed (Opened Objects [{1}])" , poolName , numberOfPooledObjectsCreated - pool.Count); } } }
0 comments: on "Object Pooling"
Post a Comment