LoaderContext の使い回し

by yasurageruheya
LoaderContext オブジェクトの parameters プロパティって便利だけど、それが使いたいがために毎回 new していたけど、使いまわしたら処理コストが少しでもマシになるのかな、と思いまして。
しかし parameters を使い回したい、って場合もたまにありますよね・・・。
♥0 | Line 259 | Modified 2015-11-17 17:53:32 | 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/AkVk
 */

package {
	import flash.display.Loader;
	import flash.display.ShaderParameter;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.geom.Rectangle;
	import flash.system.LoaderContext;
	import flash.system.System;
	import flash.text.TextField;
	import flash.text.TextFormat;
	import flash.utils.ByteArray;
	public class FlashTest extends Sprite {
		
		public const LOOP:int = 8000;
		
		public const txt:TextField = new TextField();
		
		public var tests:Vector.<Tester> = new Vector.<Tester>();
		
		private var _vec:Vector.<LoaderContext> = new Vector.<LoaderContext>(LOOP);
		
		public var freeMemory:int;
		
		public var gcCount10byte:int = 0;
		
		public var gcCount100byte:int = 0;
		
		public var gcCount1KB:int = 0;
		
		public var gcCount10KB:int = 0;
		
		public var gcCount100KB:int = 0
		
		public var gcCount1MB:int = 0;
		
		public var gcCount10MB:int = 0;
		
		public var gcCount100MB:int = 0;
		
		public var gcCount:int = 0;
		
		public var totalFrames:Number = 1;
		
		public function FlashTest() {
			
			
			tests[tests.length] = new Tester('new LoaderContext();\t\t\t\t: ', newLoaderContext);
			
			tests[tests.length] = new Tester('プールが空の状態から取り出す\t\t: ',getInstanceFromEmptyPool);
			
			tests[tests.length] = new Tester('new とプーリング\t\t\t\t\t: ', newAndPooling);
			
			tests[tests.length] = new Tester('プーリングされた状態から取り出す\t: ', getInstanceFromPool);
			
			tests[tests.length] = new Tester('プールが空の状態から取り出す2\t\t: ', getInstanceFromEmptyPool2);
			
			tests[tests.length] = new Tester('プーリングのみ\t\t\t\t\t\t: ', onlyPooling);
			
			tests[tests.length] = new Tester('プーリングと取り出し\t\t\t\t: ', getInstanceAndPooling);
			
			
			tests.reverse();
			var format:TextFormat = txt.getTextFormat();
			format.font = "_等幅";
			txt.defaultTextFormat = format;
			txt.width = 500;
			txt.height = 500;
			addChild(txt);
			
			var i:int = LOOP;
			while (i--)
			{
				_vec[i] = new LoaderContext();
			}
			
			freeMemory = System.freeMemory;
			
			// write as3 code here..
			addEventListener(Event.ENTER_FRAME, test);
		}
		
		private function test(e:Event):void 
		{
			var str:String = "";
			var i:int = tests.length;
			while (i--)
			{
				str += tests[i].start();
			}
			str += "\nmemory : total " + System.totalMemory + " / private " + System.privateMemory + "\n";
			
			const currentFreeMemory:Number = System.freeMemory;
			
			if (freeMemory < currentFreeMemory)
			{
				gcCount++;
				const gcMemory:Number = currentFreeMemory - freeMemory;
				if (gcMemory > 100000000)
				{
					gcCount100MB++;
				}
				else if (gcMemory > 10000000)
				{
					gcCount10MB++;
				}
				else if (gcMemory > 1000000)
				{
					gcCount1MB++;
				}
				else if (gcMemory > 100000)
				{
					gcCount100KB++;
				}
				else if (gcMemory > 10000)
				{
					gcCount10KB++;
				}
				else if (gcMemory > 1000)
				{
					gcCount1KB++;
				}
				else if (gcMemory > 100)
				{
					gcCount100byte++;
				}
				else if (gcMemory > 10)
				{
					gcCount10byte++;
				}
			}
			freeMemory = System.freeMemory;
			
			str += "\n100MB\tGC発生回数?\t: " + gcCount100MB;
			str += "\n10MB\tGC発生回数?\t: " + gcCount10MB;
			str += "\n1MB\t\tGC発生回数?\t: " + gcCount1MB;
			str += "\n100KB\tGC発生回数?\t: " + gcCount100KB;
			str += "\n10KB\tGC発生回数?\t: " + gcCount10KB;
			str += "\n1KB\t\tGC発生回数?\t: " + gcCount1KB;
			str += "\n100byte\tGC発生回数?\t: " + gcCount100byte;
			str += "\n10byte\tGC発生回数?\t: " + gcCount10byte;
			str += "\n\t\t計GC発生回数?\t: " + gcCount;
			
			str += "\n\t\tGC発生率?\t\t: " + ((gcCount / (totalFrames++)) * 100) + "%";
			
			txt.text = str;
		}
		
		[Inline]
		final private function newLoaderContext():void
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = new LoaderContext();
				l.parameters = { aaa:"aaa" };
			}
		}
		
		[Inline]
		final private function getInstanceFromEmptyPool():void
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = PoolLoaderContext.fromPool();
				l.parameters = { aaa:"aaa" };
			}
		}
		
		[Inline]
		final private function newAndPooling():void
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = new LoaderContext();
				l.parameters = { aaa:"aaa" };
				PoolLoaderContext.toPool(l);
			}
		}
		
		[Inline]
		final private function getInstanceFromPool():void
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = PoolLoaderContext.fromPool();
				l.parameters = { aaa:"aaa" };
			}
		}
		
		[Inline]
		final private function getInstanceFromEmptyPool2():void 
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = PoolLoaderContext.fromPool();
				l.parameters = { aaa:"aaa" };
				_vec[_vec.length] = l;
			}
		}
		
		[Inline]
		final private function onlyPooling():void 
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				PoolLoaderContext.toPool(_vec.pop());
			}
		}
		
		[Inline]
		final private function getInstanceAndPooling():void 
		{
			var i:int = LOOP;
			var l:LoaderContext;
			while (i--)
			{
				l = PoolLoaderContext.fromPool();
				l.parameters = { aaa:"aaa" };
				PoolLoaderContext.toPool(l);
			}
		}
	}
}

import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.geom.Rectangle;
import flash.system.ApplicationDomain;
import flash.system.LoaderContext;
import flash.system.SecurityDomain;
import flash.system.System;
import flash.utils.ByteArray;
import flash.utils.Dictionary;
import flash.utils.getTimer;
class Tester
{
	public var time:Number = 0;
	
	public var name:String;
	
	public var test:Function;
	
	public var count:Number = 1;
	
	public function start():String
	{
		const startTime:int = getTimer();
		test();
		time += getTimer() - startTime;
		return name + (time / (count++)) + " ms.\n";
	}
	
	public function get timeAverage():Number
	{
		return time / count;
	}
	
	public function Tester(name:String, test:Function)
	{
		this.name = name;
		this.test = test;
	}
}


class PoolLoaderContext
{
	private static const _pool:Vector.<LoaderContext> = new Vector.<LoaderContext>();
	
	[Inline]
	public static function fromPool(checkPolicyFile:Boolean=false, applicationDomain:ApplicationDomain=null, securityDomain:SecurityDomain=null):LoaderContext
	{
		var i:int = _pool.length;
		var l:LoaderContext;
		while (i--)
		{
			l = _pool.pop();
			if (!l.parameters)
			{
				l.parameters = { };
				l.checkPolicyFile = checkPolicyFile;
				l.applicationDomain = applicationDomain;
				l.securityDomain = securityDomain;
				return l;
			}
		}
		return new LoaderContext(checkPolicyFile, applicationDomain, securityDomain);
	}
	
	[Inline]
	static public function toPool(loaderContext:LoaderContext):void
	{
		if (loaderContext.parameters)
		{
			loaderContext.parameters = null;
			_pool[_pool.length] = loaderContext;
		}
	}
	
	public function PoolLoaderContext()
	{
		
	}
}