Monday 26 May 2014

Static vs non-static: vars vs consts in Adobe AIR.

I was cleaning the engine that makes Beekyr a good performing game in all platforms. And I just thought , I could try to make it perform even more by converting my static classes and vars to non static.

I got the most bizarre results....

The tests consist in accessing a variable (or const) 1 million times.


Code:
package kaleidoEngine.parts.tests
{
    import citrus.core.CitrusEngine;
    import flash.display.Sprite;
    import flash.utils.getTimer;
    import game.GameVars;
    import game.Main;
    import kaleidoEngine.parts.data.EngineVars;
    /**
     * ...
     * @author Jaime Dominguez
     */
    public class staticPerformance extends Sprite
    {
        private var resultsProperties:Array;
        private var resultsStatics:Array;
        public var tempInt:int;
        public function staticPerformance()
        {
            testA(10000000);
            testB(10000000);
          
            row("*****END TEST*******");
          
        }
      
        private function testB(_REPS:Number):void
        {
            var _game:Main = CitrusEngine.getInstance() as Main;
            var beforeTime:int;
            var afterTime:int;
            var REPS:int = _REPS;
            var i:int;
            var inte:int;
            var c:Class;
            var num:Number;
          
            var resultA:int ;
            var resultB:int ;
      
            tempInt = GameVars.DIFFICULTY_LEVEL;
            var _tempInt:int = GameVars.DIFFICULTY_LEVEL;
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = GameVars.DIFFICULTY_LEVEL;
            }
            afterTime = getTimer();
            resultA = (afterTime-beforeTime);
            row("STATIC VAR INT:" + (afterTime-beforeTime))
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                inte = tempInt;
            }
            afterTime = getTimer();
            resultB = (afterTime-beforeTime);
            row("CLASS VAR INT:" +( afterTime-beforeTime))
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                inte = _tempInt;
            }
            afterTime = getTimer();
            resultB = (afterTime-beforeTime);
            row("FUNCTION CONST INT:" +( afterTime-beforeTime))
          
            if (resultA > resultB) row ("LOCAL VAR INT IS FASTER");
            else row ("NON-LOCAL VAR INT IS FASTER");
          
          
        }
      
        public function row(text:*):void {
            trace ("[TESTING] " + text);
        }
      
        public function testA(_REPS:uint):void{
          

            var _game:Main = CitrusEngine.getInstance() as Main;
            var beforeTime:int;
            var afterTime:int;
            var REPS:int = _REPS;
            var i:int;
            var inte:int;
            var c:Class;
            var num:Number;

            row("*****Testing ["+_REPS+"]*******");

            resultsProperties = new Array();
            resultsStatics = new Array();
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = _game.gameVars.CONST_NUM;
            }
            afterTime = getTimer();
            resultsProperties.push(afterTime-beforeTime)
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = _game.gameVars.CONST_INT;
            }
            afterTime = getTimer();
            resultsProperties.push(afterTime-beforeTime)
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = _game.gameVars.VAR_NUM;
            }
            afterTime = getTimer();
            resultsProperties.push(afterTime-beforeTime)

            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                inte = _game.gameVars.VAR_INT;
            }
            afterTime = getTimer();
            resultsProperties.push(afterTime-beforeTime)

            row ("------STATICS------");
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = GameVars.ST_CONST_NUM;
            }
            afterTime = getTimer();
            resultsStatics.push(afterTime-beforeTime);
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = GameVars.ST_CONST_INT;
            }
            afterTime = getTimer();
            resultsStatics.push(afterTime-beforeTime);
          
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                num = GameVars.ST_VAR_NUM;
            }
            afterTime = getTimer();
            resultsStatics.push(afterTime-beforeTime);
      
            beforeTime = getTimer();
            for (i = 0; i < REPS; ++i)
            {
                inte = GameVars.ST_VAR_INT;
            }
            afterTime = getTimer();
            resultsStatics.push(afterTime-beforeTime);
          
   
            //row("RESULTS :    PROPERTY   VS  STATIC ");
            //row("CONST NUM:" +resultsProperties[0] +" vs. " + resultsStatics[0] )
            if (resultsProperties[0] > resultsStatics[0]) row("CONST NUM: STATIC FASTER");
            else row("CONST NUM: PROPERTY FASTER");
            //row("-----------------");
            //row("CONST INT:" +resultsProperties[1] +" vs. " + resultsStatics[1] )
            if (resultsProperties[1] > resultsStatics[1]) row("CONST INT: STATIC FASTER");
            else row("CONST INT: PROPERTY FASTER");
            //row("-----------------");
            //row("VAR NUM:" +resultsProperties[2] +" vs. " + resultsStatics[2] )
            if (resultsProperties[2] > resultsStatics[2]) row("VAR NUM: STATIC FASTER");
            else row("VAR NUM: PROPERTY FASTER");
            //row("-----------------");
            //row("VAR INT:" +resultsProperties[3] +" vs. " + resultsStatics[3] )
            if (resultsProperties[3] > resultsStatics[3]) row("VAR INT: STATIC FASTER");
            else row("VAR INT: PROPERTY FASTER");
            //row("-----------------");

          
        }
    }

}


You will need to create a GameVars class to host all variables
And a _game class that has gameVars as GameVars


Results....

Test 1:

Int / Number (they take same time but only sometimes int is faster):

public const int : 7 ms; (this looks pretty fast!)
static public const int : 82 ms;


Number:
public var Number : 97 ms;
static public var Number : 86 ms;

Int:
public var int : 84 ms;
static public var int : 86 ms;


Test 2:        
If I copy a static var (int) to a local var int
static public var int : 89 ms (external to from that object)
public var int : 87 ms (class var)

 


So results are:
Test 1:
The fastest are NON-STATIC CONSTS

Test 2:
If copy static var to a local class or function var and then re-use that new var, makes a very little performance improvement... and only sometimes.

My conclusion is that only non-static consts are really fast. The rest are kind of the same.

Please do your tests and let us know, I'm not sure If I made some mistake because it makes little sense to me....




No comments: