package { //{ region imports import flash.display.Sprite; import flash.events.Event; import flash.utils.*; //} endregion public class ArrayBenchmark extends Sprite { private var _benchmarks:Array = []; public function ArrayBenchmark() { this.addEventListener(Event.ENTER_FRAME, nextBench); this.benchmark("Vector as Vector.", this.benchmarkVector, []); this.benchmark("Vector as *", this.benchmarkCollectionAsAny, [function ():* { return new Vector.<*>(); } ]); this.benchmark("Vector as Object", this.benchmarkCollectionAsObject, [function ():* { return new Vector.<*>(); } ]); this.benchmark("Array as Array", this.benchmarkArray); this.benchmark("Array as *", this.benchmarkCollectionAsAny, [Array]); this.benchmark("Array as Object", this.benchmarkCollectionAsObject, [Array]); this.benchmark("Dictionary as Dictionary", this.benchmarkDict); this.benchmark("Dictionary as *", this.benchmarkCollectionAsAny, [Dictionary]); this.benchmark("Dictionary as Object", this.benchmarkCollectionAsObject, [Dictionary]); this.benchmark("Object as *", this.benchmarkCollectionAsAny, [Object]); this.benchmark("Object as Object", this.benchmarkCollectionAsObject, [Object]); } private function nextBench(e:Event):void { if (this._benchmarks.length > 0) this.doBenchmark.apply(this, this._benchmarks.pop()); else this.removeEventListener(Event.ENTER_FRAME, nextBench); } private function doBenchmark(test:String, method:Function, args:Array = null, repetitions:uint = 200, size:uint = 500000):void { trace("testing " + test); trace(repetitions + " repetitions with collections of size " + size); var forLoops:uint = 0; var forEachLoops:uint = 0; args = [size].concat(args == null ? [] : args); for (var i:int = 0; i < repetitions; i++) { var result:Result = method.apply(null, args); forLoops += result.forLoop; forEachLoops += result.forEachLoop; } trace("\t> for loops needed " + (forLoops / repetitions) + " msecs"); trace("\t> for each loops needed " + (forEachLoops / repetitions) + " msecs"); trace("\t> factor: " + (forLoops / forEachLoops)); trace("\n"); } private function benchmark(test:String, method:Function, args:Array = null, repetitions:uint = 200, size:uint = 500000):void { this._benchmarks.unshift(arguments); } private function benchmarkCollectionAsObject(size:uint, constructor:*):Result { //setup iterable with size entries var iterable:Object; if (constructor is Class) iterable = new constructor(); else iterable = constructor(); for (var i:int = 0; i < size; i++) iterable[i] = i; var start:uint, key:uint, value:Object, ret:Result = new Result(); start = getTimer(); for (key = 0; key < size; key++) value = iterable[key]; ret.forLoop = getTimer() - start; start = getTimer(); key = 0; for each (value in iterable) key++; ret.forEachLoop = getTimer() - start; return ret; } private function benchmarkCollectionAsAny(size:uint,constructor:*):Result { //setup iterable with size entries var iterable:*; if (constructor is Class) iterable = new constructor(); else iterable = constructor(); for (var i:int = 0; i < size; i++) iterable[i] = i; var start:uint, key:uint, value:Object, ret:Result = new Result(); start = getTimer(); for (key = 0; key < size; key++) value = iterable[key]; ret.forLoop = getTimer() - start; start = getTimer(); key = 0; for each (value in iterable) key++; ret.forEachLoop = getTimer() - start; return ret; } private function benchmarkVector(size:uint):Result { //setup vector with size entries var vector:Vector. = new Vector.(size,true); for (var i:int = 0; i < size; i++) vector[i] = i; var start:uint, key:uint, value:int, ret:Result = new Result(); start = getTimer(); for (key = 0; key < size; key++) value = vector[key]; ret.forLoop = getTimer() - start; start = getTimer(); key = 0; for each (value in vector) key++; ret.forEachLoop = getTimer() - start; return ret; } private function benchmarkArray(size:uint):Result { //setup array with size entries var array:Array = []; for (var i:int = 0; i < size; i++) array.push(i); var start:uint, key:uint, value:Object, ret:Result = new Result(); start = getTimer(); for (key = 0; key < size; key++) value = array[key]; ret.forLoop = getTimer() - start; start = getTimer(); key = 0; for each (value in array) key++; ret.forEachLoop = getTimer() - start; return ret; } private function benchmarkDict(size:uint):Result { //setup dict with size entries var dict:Dictionary = new Dictionary(); for (var i:int = 0; i < size; i++) dict[i] = i; var start:uint, key:uint, value:Object, ret:Result = new Result(); start = getTimer(); for (key = 0; key < size; key++) value = dict[key]; ret.forLoop = getTimer() - start; start = getTimer(); key = 0; for each (value in dict) key++; ret.forEachLoop = getTimer() - start; return ret; } } } class Result { public var forLoop:uint; public var forEachLoop:uint; public function Result() { }; }