Rectangle やら ColorTransform やらをとにかく使いまわす

by yasurageruheya
リアルタイムに範囲を指定してどんどこキャプチャする時に、Rectangleやらなんやらをcloneしたりしまくる必要があったので、またさらに処理をちょっとだけでも高速化したかったので、処理速度のテストをしたかった。
♥0 | Line 146 | Modified 2015-02-13 19:13:47 | 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/nENT
 */

package {
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.display.StageQuality;
	import flash.events.Event;
	import flash.geom.ColorTransform;
	import flash.geom.Matrix;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.system.System;
	import flash.text.TextField;
	import flash.utils.ByteArray;
	public class FlashTest extends Sprite {
		
		public const LOOP:int = 50000;
		
		public const txt:TextField = new TextField();
		
		public var tests:Vector.<Tester> = new Vector.<Tester>();
		
		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 var vec_byte:Vector.<ByteArray> = new Vector.<ByteArray>();
		
		public function FlashTest() {
			
			var vec:Vector.<Rectangle> = new Vector.<Rectangle>(LOOP);
			var count:int = 0;
			
			stage.frameRate = 1000;
			
			var originalRectangle:Rectangle = new Rectangle();
			var originalMatrix:Matrix = new Matrix();
			var originalColorTransform:ColorTransform = new ColorTransform();
			var originalPoint:Point = new Point();
			
			var cloneRectangle:Rectangle = new Rectangle();
			var cloneMatrix:Matrix = new Matrix();
			var cloneColorTransform:ColorTransform = new ColorTransform();
			var clonePoint:Point = new Point();
			
			//*
			tests[tests.length] = new Tester("rectangle 生clone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					originalRectangle.clone();
				}
			});
			
			tests[tests.length] = new Tester("matrix 生clone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					originalMatrix.clone();
				}
			});
			
			tests[tests.length] = new Tester("point 生clone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					originalPoint.clone();
				}
			});
			
			tests[tests.length] = new Tester("rectangle カスタムclone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					RectangleUtil.clone(originalRectangle);
				}
			});
			
			tests[tests.length] = new Tester("matrix カスタムclone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					MatrixUtil.clone(originalMatrix);
				}
			});
			
			tests[tests.length] = new Tester("colorTransform カスタムclone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					ColorTransformUtil.clone(originalColorTransform);
				}
			});
			
			tests[tests.length] = new Tester("point カスタムclone : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					PointUtil.clone(originalPoint);
				}
			});
			
			tests[tests.length] = new Tester("rectangle 事前に new された物にコピー : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					RectangleUtil.clone(originalRectangle, cloneRectangle);
				}
			});
			
			tests[tests.length] = new Tester("matrix 事前に new された物にコピー : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					MatrixUtil.clone(originalMatrix, cloneMatrix);
				}
			});
			
			tests[tests.length] = new Tester("colorTransform 事前に new された物にコピー : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					ColorTransformUtil.clone(originalColorTransform, cloneColorTransform);
				}
			});
			
			tests[tests.length] = new Tester("point 事前に new された物にコピー : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					PointUtil.clone(originalPoint, clonePoint);
				}
			});
			/*/
			tests[tests.length] = new Tester("new Rectangle() : ", function():void
			{
				var i:int = LOOP;
				while (i--)
				{
					new Rectangle();
				}
			});
			//*/
			
			tests.reverse();
			txt.width = 500;
			txt.height = 500;
			addChild(txt);
			
			freeMemory = System.freeMemory;
			
			// write as3 code here..
			addEventListener(Event.ENTER_FRAME, test);
		}
		
		private var testIndex:int = 0;
		
		private function test(e:Event):void 
		{
			var str:String = "";
			tests[testIndex].start();
			testIndex++;
			if (tests.length <= testIndex) testIndex = 0;
			var i:int = tests.length;
			while (i--)
			{
				str += tests[i].message;
			}
			/*if (tests.length > 1)
			{
				str += "プーリングと取り出しの合計 : " + (tests[0].timeAverage + tests[1].timeAverage) + " ms.\n";
			}*/
			/*str += "memory : 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\t\tGC発生回数?\t: " + gcCount10MB;
			str += "\n1MB\t\tGC発生回数?\t: " + gcCount1MB;
			str += "\n100KB\t\tGC発生回数?\t: " + gcCount100KB;
			str += "\n10KB\t\tGC発生回数?\t: " + gcCount10KB;
			str += "\n1KB\t\tGC発生回数?\t: " + gcCount1KB;
			str += "\n100byte\tGC発生回数?\t: " + gcCount100byte;
			str += "\n10byte\t\tGC発生回数?\t: " + gcCount10byte;
			str += "\n\t\t\tGC発生回数?\t: " + gcCount;
			
			str += "\n\t\t\tGC発生率?\t: " + ((gcCount / (totalFrames++)) * 100) + "%";*/
			
			txt.text = str;
		}
	}
}

import flash.geom.ColorTransform;
import flash.geom.Matrix;
import flash.geom.Point;
import flash.geom.Rectangle;
import flash.system.System;
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 message():String
	{
		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 MatrixUtil
{
	[Inline]
	public static function clone(source:Matrix, copy:Matrix = null):Matrix
	{
		copy = copy || new Matrix();
		copy.a	= source.a;
		copy.b	= source.b;
		copy.c	= source.c;
		copy.d	= source.d;
		copy.tx	= source.tx;
		copy.ty	= source.ty;
		return copy;
	}
}

class RectangleUtil
{
	[Inline]
	public static function clone(source:Rectangle, copy:Rectangle = null):Rectangle
	{
		copy = copy || new Rectangle();
		copy.x = source.x;
		copy.y = source.y;
		copy.width = source.width;
		copy.height = source.height;
		return copy;
	}
}

class ColorTransformUtil
{
	[Inline]
	public static function clone(source:ColorTransform, copy:ColorTransform = null):ColorTransform
	{
		if (!copy)
		{
			return new ColorTransform(source.redMultiplier, source.greenMultiplier, source.blueMultiplier, source.alphaMultiplier, source.redOffset, source.greenOffset, source.blueOffset, source.alphaOffset);
		}
		
		copy.alphaMultiplier = source.alphaMultiplier;
		copy.alphaOffset = source.alphaOffset;
		copy.blueMultiplier = source.blueMultiplier;
		copy.blueOffset = source.blueOffset;
		copy.greenMultiplier = source.greenMultiplier;
		copy.greenOffset = source.greenOffset;
		copy.redMultiplier = source.redMultiplier;
		copy.redOffset = copy.redOffset;
		return copy;
	}
}

class PointUtil
{
	[Inline]
	public static function clone(source:Point, copy:Point = null):Point
	{
		copy = copy || new Point();
		copy.x = source.x;
		copy.y = source.y;
		return copy;
	}
}