Using object pools(使用对象池)
2010-11-11 15:09
211 查看
Using object pools
Joa Ebertis right when he says that utilizing object pools can make your code
perform a lot faster. An object pool is just a container for a bunch of
pre-constructed objects that are kept in memory ready for use, rather
than being repeatedly allocated and destroyed on demand.
Object pooling makes sense if:
you create dozens of short-lived objects in real-time applications like games
you need to store and share temporary data throughout complex algorithms
the objects are expensive to create (many fields, complex inheritance chain, nested objects)
the objects are expensive to remove (unregister listeners, nullify instances)
The only drawback is that memory consumption will raise, but with
ridiculously low memory prices this shouldn’t be problem if used wisely
;-)
Implementation
So here is my ObjectPool.asmanager class which is an
attempt to create a lightweight, fast and reusable solution. The
implementation is based on a circular list, and the API is very simple.
Download: ObjectPool_v1.0.zip
(source, example, asdoc)
EDIT
I have updated the class so it also accepts a factory for object construction.
Download: ObjectPool_v1.1.zip
First, we create the object pool:
var isDynamic : Boolean = true ; var size : int = 100 ; var pool : ObjectPool = new ObjectPool ( isDynamic ); pool . allocate ( MyClass , size );
The isDynamic
flag defines the behavior for an empty pool.
If true, the pool automatically creates a new bunch of objects for you.
If false, the class throws an Error to indicate that the pool is empty.
The size
value indicates the pool’s capacity – if the pool is
dynamic, the pool grows by the initial size each time it becomes empty
so it actually never dries up.
By calling the allocate method the pool is filled with 100 instances
of MyClass. You can always reuse the pool for another Class by invoking
this method again.
If you need to initialize the objects by passing arguments to it, you can do this with a little helper method called initialize:
pool . initialize ( "funcName" , [ arg0 , arg1 ,...]);
This goes through every object and applies the function with the
given arguments upon each object. This can also be done by reading each
object, calling the function and putting it back:
for ( var i : int = 0 ; i < pool . size ; i ++) { var o : MyClass = pool . object ; o . init ( arg0 , arg1 , ...); pool . object = o ; }
Now to get an instance of MyClass you access the pool like this:
myObjectArray [ i ] = pool . instance ; //instead of myObjectArray [ i ] = new MyClass ();
When you are done with your object, instead of throwing it into the garbage collector, you "recycle" it for the next use:
pool . instance = myObjectArray [ i ];
This assumes that you are storing your instances in an array or
something else because if you loose the reference, well it's lost and
can't be reused anymore :-) And be careful not to assign the object
twice, since then your pool would contain duplicates of the same object!
That's all, pretty simple right ?
Finally, there is the purge() method, which is only interesting for
pools that are dynamic. As the pool grows with the demands of the
application, it can get quite big. The purge methods scans the pool and
removes all allocated but currently unused objects, leaving with a
compact representation.
Demo
Here is a little demo which demonstrations how the pool worksinternally. Actually it's very simple. Pressing the RIGHT arrow key
reads an object from the pool (first row), which is then stored in the
second row beneath. Pressing the LEFT arrow key gives the object back to
the pool. Pressing the ENTER key performs a purge() operation. The
purple circle points to the node where the next object is read, the blue
circle to an empty node where the insertion is performed.
Performance
Benchmarking revealed that it's always faster to cache instances,even for the generic Object class. All benchmarks were done with the
release player 9.0.124 on Vista, an object pool size of 100 and with 100
iterations each to get an average value.
The purple bar indicates the time needed to access the pool:
for ( var i : int = 0 ; i < k ; i ++) instances [ i ] = p . instance ;
The blue bar measures the task of reading the objects, then putting them back:
for ( i = 0 ; i < k ; i ++) instances [ i ] = p . instance ; for ( i = 0 ; i < k ; i ++) p . instance = instances [ i ];
The grey bar shows the time needed for creating the objects on the fly:
for ( i = 0 ; i < k ; i ++) instances [ i ] = new MyClass ();
Here my result:
Caching a native flash Object can be almost 5x faster instead of creating it on the fly.
Almost the same applies to a slightly more complex object like the flash.geom.Point class.
Creating complex objects, here from the flash.display.Sprite class, is extremely slow and up
to 80x faster when pooling.
转载:http://lab.polygonal.de/2008/06/18/using-object-pools/
相关文章推荐
- 为什么已经引用了using System.Management 使用ManagementObjectSearcher时为什么提示未引用空间?
- 3_使用指针对象(Using Object Pointer)
- 什么情况下应该使用对象池(ObjectPool)?
- android中使用对象池 ----- Pools
- SP2010开发和VS2010专家"食谱"--第七章节--使用客户端对象模型(4)--Using JavaScript Object Model
- unity - 对象池(Object Pools)
- SP2010开发和VS2010专家"食谱"--第七章节--使用客户端对象模型(4)--Using JavaScript Object Model
- OpenCV_(Using GrabCut extract the foreground object) 使用 GrabCut 算法提取前景物体
- 什么情况下应该使用对象池(ObjectPool)
- Using object pools (内存换效率)
- xcode 7种使用coredata遇到 Class not found, using default NSManagedObject instead.问题
- SP2010开发和VS2010专家"食谱"--第七章节--使用客户端对象模型(5)--Using a Silverlight Object Model
- SP2010开发和VS2010专家"食谱"--第七章节--使用客户端对象模型(5)--Using a Silverlight Object Model
- 使用对象池(ObjectPool)方式处理子弹的发射逻辑
- 关于spring.net的面向切面编程 (Aspect Oriented Programming with Spring.NET)-使用工厂创建代理(Using the ProxyFactoryObject to create AOP proxies)
- 使用json-lib的JSONObject.toBean( )时碰到的日期属性转换的问题
- cocos2dx button的使用以及cocostudio/ObjectFactory.h: No such file or directory错误解决方案
- Flash 中 Object.registerClass("linkname":String,class:Object) 一点使用体会
- SqlConnection的dispose和close方法差异和using的使用选择
- SSH使用QBC查询时无法将查处的集合存入实体集合中,而是返回Object[]