package { import flash.display.MovieClip; import flash.events.Event; import flash.text.TextField; import flash.text.TextFormat; import flash.text.TextFieldAutoSize; import flash.utils.ByteArray; import flash.utils.getTimer; /** * ... * @author ... */ public class Array1DvsArray2D extends MovieClip { private const USEOBJECTS:Boolean = true //true = fill the maps with objects : false = fill the map with integers // private var mode:int = 1 private var reportField:TextField = new TextField() private var reportField2:TextField = new TextField() private var reportField3:TextField = new TextField() // private var Test:int = 1 private var TotalTests:int = 10 private var Samples1D:Array = [] //stores the times for analysis private var Samples2D:Array = [] //stores the times for analysis private var Samples1DVector:Array = [] //stores the times for analysis private var Samples2DVector:Array = [] //stores the times for analysis private var Samples1DByte:Array = [] //stores the times for analysis private var Samples2DByte:Array = [] //stores the times for analysis private var columns:int = 1024 //the amount of columns in the tilemap (use a power of 2 for best results) private var rows:int = 1024 //the amount of rows in the tilemap (use a power of 2 for best results) private var columnBytes:int //the number of bytes a row uses // private var time1Da:int private var time1Db:int private var time2Da:int private var time2Db:int private var time1DaVector:int private var time1DbVector:int private var time2DaVector:int private var time2DbVector:int private var time1DaByte:int private var time1DbByte:int private var time2DaByte:int private var time2DbByte:int // private var Array1D:Array = [] //1D tilemap private var Array2D:Array = [] //2D tilemap private var Vector1D:Vector. private var Vector2D:Vector.> private var Vector1DObject:Vector. private var Vector2DObject:Vector.> private var Byte1D:ByteArray = new ByteArray() private var Byte2D:ByteArray = new ByteArray() // //============= // CONSTRUCTOR //============= public function Array1DvsArray2D():void { trace("connected") createReportFields() createMaps() // // UPDATE EVENT // addEventListener(Event.ENTER_FRAME, update) } private function createReportFields():void { reportField.autoSize = TextFieldAutoSize.LEFT reportField.multiline = true reportField.htmlText = " " reportField2.autoSize = TextFieldAutoSize.LEFT reportField2.multiline = true reportField2.htmlText = " " reportField3.autoSize = TextFieldAutoSize.LEFT reportField3.multiline = true reportField3.htmlText = " " var reportFormat:TextFormat = new TextFormat() reportFormat.font = "Verdana" reportFormat.size = 8 reportField.defaultTextFormat = reportFormat reportField2.defaultTextFormat = reportFormat reportField3.defaultTextFormat = reportFormat reportField.x = 0 reportField2.x = 200 reportField3.x = 400 addChild(reportField) addChild(reportField2) addChild(reportField3) } private function createMaps():void { // // ARRAY & VECTOR & BYTEARRAY CREATION // var useObjects:Boolean = USEOBJECTS var X:int var Y:int var currentColumn:Array var currentColumnV:Vector. var currentColumnVObject:Vector. var currentColumnB:ByteArray var toPush Vector1D = new Vector.(rows * columns); Vector2D = new Vector.>(columns) Vector1DObject = new Vector.(rows * columnBytes) Vector2DObject = new Vector.>(columns) // for(X = 0; X < columns; X++){ currentColumn = [] currentColumnV = new Vector.(columns) currentColumnVObject = new Vector.(columns) currentColumnB = new ByteArray() for (Y = 0; Y < rows; Y++) { if (useObjects) { toPush = new Object() } else { toPush = Math.random() * 30 } // currentColumn.push(toPush) currentColumnB.writeInt(toPush) // Array1D.push(toPush) if (useObjects) { currentColumnVObject[Y] = toPush Vector1DObject[X * rows | Y] = toPush } else { currentColumnV[Y] = toPush Byte1D.writeInt(toPush) Vector1D[X * rows | Y] = toPush } } Array2D.push(currentColumn) if (useObjects) { Vector2DObject[X] = currentColumnVObject } else { Vector2D[X] = currentColumnV Byte2D.writeObject(currentColumnB) } } columnBytes = Byte2D.length / columns // trace("==== UnitTest ====") if (useObjects) { trace("Array1D " + getObject1D(1, 1)) trace("Vector1D " + getObject1DVector(1, 1)) trace("Array2D " + getObject2D(1, 1)) trace("Vector2D " + getObject2DVector(1, 1)) } else { trace("Array1D " + getInt1D(1, 1)) trace("Vector1D " + getInt1DVector(1, 1)) trace("Byte1D " + getInt1DByte(1, 1)) trace("Array2D " + getInt2D(1, 1)) trace("Vector2D " + getInt2DVector(1, 1)) trace("Byte2D " + getInt2DByte(1, 1)) } /*trace("==================") trace("Array1D " + Array1D) trace("==") trace("Array21D " + Array2D) trace("==") trace("Vector1D " + Vector1D) trace("==") trace("Vector2D " + Vector2D) trace("==================")*/ } //============== // UPDATE CYCLE //============== private function update(e:Event):void { // // RUN TEST (only one per frame) // var useObjects:Boolean = USEOBJECTS switch(mode) { case 1: //1D Array speedtest trace("1D array test") time1Da = getTimer() if(useObjects){ test1DObject() } else { test1D() } time1Db = getTimer() break; case 2: //2D Array speedtest trace("2D array test") time2Da = getTimer() if (useObjects) { test2DObject() } else { test2D() } time2Db = getTimer() break; case 3: //1D Vector speedtest trace("1D vector test") time1DaVector = getTimer() if (useObjects) { test1DVectorObject() } else { test1DVector() } time1DbVector = getTimer() break; case 4: //2D Vector speedtest trace("2D vector test") time2DaVector = getTimer() if (useObjects) { test2DVectorObject() } else { test2DVector() } time2DbVector = getTimer() break; case 5: //1D ByteArray speedtest trace("1D byteArray test") if (!useObjects) { time1DaByte = getTimer() test1DByte() time1DbByte = getTimer() } break; case 6: //2D ByteArray speedtest /*trace("2D byteArray test") time2DaByte = getTimer() test2DByte() time2DbByte = getTimer()*/ break; case 7: // // REPORT // var Delta1D:Number = time1Db - time1Da var Delta2D:Number = time2Db - time2Da // var Delta1DVector:Number = time1DbVector - time1DaVector var Delta2DVector:Number = time2DbVector - time2DaVector // if(!useObjects){ var Delta1DByte:Number = time1DbByte - time1DaByte var Delta2DByte:Number = time2DbByte - time2DaByte } // var Perc:Number = Delta1D / Delta2D * 100 var PercVector1D:Number = Delta1DVector / Delta2D * 100 var PercVector2D:Number = Delta2DVector / Delta2D * 100 if(!useObjects){ var PercByte1D:Number = Delta1DByte / Delta2D * 100 var PercByte2D:Number = Delta2DByte / Delta2D * 100 } // Samples1D.push(Delta1D) Samples2D.push(Delta2D) Samples1DVector.push(Delta1DVector) Samples2DVector.push(Delta2DVector) if(!useObjects){ Samples1DByte.push(Delta1DByte) Samples2DByte.push(Delta2DByte) } // TRACE("==== TEST" + Test.toString() + "/" + TotalTests.toString() + " ====") TRACE2(" ") TRACE("Arrays") TRACE("1Dtime ("+Perc.toFixed((2))+"%) = "+Delta1D.toString()+"ms") TRACE("2Dtime (100.00%) = " + Delta2D.toString() + "ms") TRACE2("Vectors") TRACE2("1Dtime ("+PercVector1D.toFixed((2))+"%) = "+Delta1DVector.toString()+"ms") TRACE2("2Dtime (" + PercVector2D.toFixed((2)) + "%) = " + Delta2DVector.toString() + "ms") TRACE3(" ") if(!useObjects){ TRACE3("ByteArrays") TRACE3("1Dtime ("+PercByte1D.toFixed((2))+"%) = "+Delta1DByte.toString()+"ms") TRACE3(" ")//TRACE3("2Dtime ("+PercByte2D.toFixed((2))+"%) = "+Delta2DByte.toString()+"ms") } // // CHECK IF ALL TESTS ARE RUN // Test++ if (Test <= TotalTests) { mode = 0 } else { statistics() removeEventListener(Event.ENTER_FRAME, update) } break; } mode++ } //=========== // FUNCTIONS //=========== private function TRACE(MESSAGE):void { reportField.htmlText += MESSAGE.toString() trace(MESSAGE) } private function TRACE2(MESSAGE):void { reportField2.htmlText += MESSAGE.toString() trace(MESSAGE) } private function TRACE3(MESSAGE):void { reportField3.htmlText += MESSAGE.toString() trace(MESSAGE) } //===================== // SPEEDTEST FUNCTIONS //===================== //INTEGERS private function getInt1D(X:int, Y:int):int { return(Array1D[X*rows | Y]) } private function getInt2D(X:int, Y:int):int { return(Array2D[X][Y]) } private function getInt1DVector(X:int, Y:int):int { return(Vector1D[X*rows | Y]) } private function getInt2DVector(X:int, Y:int):int { return(Vector2D[X][Y]) } private function getInt1DByte(X:int, Y:int):int { Byte1D.position = (X * rows | Y)*4 //An integer takes up 4 bytes return(Byte1D.readInt()) //return(Byte1D[X*rows | Y]) } private function getInt2DByte(X:int, Y:int):int { Byte2D.position = X*columnBytes var Column:ByteArray = Byte2D.readObject() Column.position = Y * 4 //An integer takes up 4 bytes return(Column.readInt()) } private function test1D():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt1D(X,Y) } } } private function test2D():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt2D(X, Y) } } } private function test1DVector():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt1DVector(X,Y) } } } private function test2DVector():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt2DVector(X,Y) } } } private function test1DByte():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt1DByte(X, Y) } } } private function test2DByte():void { var X:int var Y:int var checkValue:int for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getInt2DByte(X,Y) } } } //OBJECTS private function getObject1D(X:int, Y:int):Object { return(Array1D[X*rows | Y]) } private function getObject2D(X:int, Y:int):Object { return(Array2D[X][Y]) } private function getObject1DVector(X:int, Y:int):Object { return(Vector1DObject[X*rows | Y]) } private function getObject2DVector(X:int, Y:int):Object { return(Vector2DObject[X][Y]) } private function test1DObject():void { var X:int var Y:int var checkValue:Object for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getObject1D(X,Y) } } } private function test2DObject():void { var X:int var Y:int var checkValue:Object for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getObject2D(X, Y) } } } private function test1DVectorObject():void { var X:int var Y:int var checkValue:Object for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getObject1DVector(X,Y) } } } private function test2DVectorObject():void { var X:int var Y:int var checkValue:Object for(X = 0; X < columns; X++){ for(Y = 0; Y < rows; Y++){ checkValue = getObject2DVector(X,Y) } } } //====================== // ANALYTICAL FUNCTIONS //====================== private function mean(ARRAY:Array):Number{ var i:int var Length:int = ARRAY.length var Total:int for(i = 0; i < ARRAY.length; i++){ Total += ARRAY[i] } return(Total/Length) } private function stdDev(ARRAY:Array):Number { var MEAN:Number = mean(ARRAY) // var SE:int //Squared Error var SSE:int //Sum of Squares Error var X:int var i:int var Length:int = ARRAY.length for(i = 0; i < Length; i++){ X = ARRAY[i] SE = (X - MEAN) * (X - MEAN) SSE += SE } // var STDDEV:Number = Math.sqrt(SSE/Length) return(STDDEV) } private function statistics():void { var useObjects:Boolean = USEOBJECTS TRACE("============") TRACE(" STATISTICS") TRACE("============") TRACE2(" ") TRACE2(" ") TRACE2(" ") TRACE3(" ") TRACE3(" ") TRACE3(" ") var Mean1D:Number = mean(Samples1D) var Mean2D:Number = mean(Samples2D) var Mean1DVector:Number = mean(Samples1DVector) var Mean2DVector:Number = mean(Samples2DVector) if(!useObjects){ var Mean1DByte:Number = mean(Samples1DByte) var Mean2DByte:Number = mean(Samples2DByte) } // var stdDev1D:Number = stdDev(Samples1D) var stdDev2D:Number = stdDev(Samples2D) var stdDev1DVector:Number = stdDev(Samples1DVector) var stdDev2DVector:Number = stdDev(Samples2DVector) if(!useObjects){ var stdDev1DByte:Number = stdDev(Samples1DByte) var stdDev2DByte:Number = stdDev(Samples2DByte) } // var Perc:Number = Mean1D / Mean2D * 100 var PercVector1D:Number = Mean1DVector / Mean2D * 100 var PercVector2D:Number = Mean2DVector / Mean2D * 100 if(!useObjects){ var PercByte1D:Number = Mean1DByte / Mean2D * 100 var PercByte2D:Number = Mean2DByte / Mean2D * 100 } // TRACE("Arrays") TRACE("1D: µ = " + Mean1D.toFixed(2) + " (" + Perc.toFixed(2) + "%) σ = " + stdDev1D.toFixed(10)) TRACE("2D: µ = " + Mean2D.toFixed(2) + " (100.00%) σ = " + stdDev2D.toFixed(10)) TRACE2("Vectors") TRACE2("1D: µ = " + Mean1DVector.toFixed(2) + " (" + PercVector1D.toFixed(2) + "%) σ = " + stdDev1DVector.toFixed(10)) TRACE2("2D: µ = " + Mean2DVector.toFixed(2) + " (" + PercVector2D.toFixed(2) + "%) σ = " + stdDev2DVector.toFixed(10)) if(!useObjects){ TRACE3("ByteArrays") TRACE3("1D: µ = " + Mean1DByte.toFixed(2) + " (" + PercByte1D.toFixed(2) + "%) σ = " + stdDev1DByte.toFixed(10)) //TRACE3("2D: µ = " + Mean2DByte.toFixed(2) + " (" + PercByte2D.toFixed(2) + "%) σ = " + stdDev2DByte.toFixed(10)) } } } }