BitmapDataをどうプールするべきか

by yasurageruheya
プールするとか以前にボタンをダブルクリックとかしちゃうとめっちゃ処理に時間かかるみたいだから、クリックしてから処理が終わるまでの間はボタンのリスナー削除しとかなきゃいかんね
♥0 | Line 119 | Modified 2011-05-31 09:06:06 | MIT License
play

ActionScript3 source code

/**
 * Copyright yasurageruheya ( http://wonderfl.net/user/yasurageruheya )
 * MIT License ( http://www.opensource.org/licenses/mit-license.php )
 * Downloaded from: http://wonderfl.net/c/mrZU
 */

package {
	import flash.display.Graphics;
    import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.getTimer;
	import flash.display.BitmapData;
    public class FlashTest extends Sprite {
		private var pooler:BitmapDataPooler;
		
		private var txt:Vector.<TextField>;
		
		private const COUNT:int = 30000;
		
        public function FlashTest() {
            // write as3 code here..
            pooler = new BitmapDataPooler();
			
			txt = new Vector.<TextField>(5);
			
			var i:int = txt.length;
			while (i--)
			{
				txt[i] = new TextField();
				txt[i].autoSize = "left";
				txt[i].y = i * 20;
				addChild(txt[i]);
			}
			
			var btn:Sprite = new Sprite();
			var btn_txt:TextField = new TextField();
			btn_txt.autoSize = "left";
			btn_txt.selectable = false;
			btn_txt.text = "one more test";
			btn_txt.textColor = 0xFFFFFF;
			btn.addChild(btn_txt);
			
			var g:Graphics = btn.graphics;
			
			g.beginFill(0xFF << 24, 1);
			g.drawRect(0, 0, btn.width, btn.height);
			g.endFill();
			
			btn.y = 150;
			addChild(btn);
			
			btn.addEventListener(MouseEvent.CLICK, test);
			
			test(null);
        }
		
		private function test(e:MouseEvent):void 
		{
			var time:int = getTimer();
			var i:int = COUNT;
			var bmd:BitmapData = new BitmapData(10, 10, true, 0x0);
			while (i--)
			{
				pooler.dispose2(bmd);
			}
			
			txt[0].text = String(getTimer() - time) + " msec : プールに貯めるのにかかった時間";
			time = getTimer();
			
			i = COUNT;
			while (i--)
			{
				bmd = pooler.getNamamono();
			}
			
			txt[1].text = String(getTimer() - time) + " msec : プールからfillRectで透明にしてから取り出すのにかかった時間";
			
			i = COUNT;
			var vec:Vector.<BitmapData> = new Vector.<BitmapData>(i);
			while (i--)
			{
				vec[i] = new BitmapData(10, 10, true, 0x0);
			}
			
			time = getTimer();
			
			i = COUNT;
			while (i--)
			{
				pooler.dispose1(vec.pop());
			}
			
			txt[2].text = String(getTimer() - time) + " msec : プールに貯めたように見せかけるのにかかった時間";
			
			time = getTimer();
			
			i = COUNT;
			while (i--)
			{
				bmd = pooler.getClone();
			}
			
			txt[3].text = String(getTimer() - time) + " msec : プールから取り出したかのようにclone()するのにかかった時間";
			
			i = COUNT;
			while (i--)
			{
				bmd = new BitmapData(10, 10, true, 0x0);
			}
			
			txt[4].text = String(getTimer() - time) + " msec : 普通にnewするのにかかった時間";
			
		}
    }
}

import flash.display.BitmapData
class BitmapDataPooler
{
	private var pool:Vector.<BitmapData>;
	
	public function getClone():BitmapData
	{
		var bmd:BitmapData = pool[0];
		return bmd.clone();
	}
	
	public function getNamamono():BitmapData
	{
		var bmd:BitmapData = pool.pop();
		bmd.fillRect(bmd.rect, 0x0);
		return bmd;
	}
	
	public function dispose1(bmd:BitmapData):void
	{
		if (pool.length)
		{
			//bmd.dispose();
		}
		else
		{
			bmd.fillRect(bmd.rect, 0x0);
			pool.push(bmd);
		}
	}
	
	public function dispose2(bmd:BitmapData):void
	{
		pool.push(bmd);
	}
	
	public function BitmapDataPooler()
	{
		pool = new Vector.<BitmapData>();
	}
}