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