[AS3] Precise Timer approach #1

If you need to implement a ordinary countdown in your Flex/AIR or plain Flash application there is no way around the Flash built in Timer (flash.utils.Timer, since 9.0). Unfortunately this Timer isn’t accurate, not even close. Even worse, the longer it runs, the more it will be off time. Traced out the first 20 seconds of a simple Timer which fires every 1000ms, we are 1800ms off!

1001
2110
3262
4340
5583
6678
7757
8836
9908
10986
12081
13149
14235
15312
16383
17460
18543
19633
20712
21837

So I did some tests with setInterval, a hangover function from AS2, which lead me to the same result. Since I needed a timer that runs accurate my idea was to calculate the gap on every cycle and adjust the internal timer. Use it just like the normal Timer.

package
{

import flash.events.EventDispatcher;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.utils.getTimer;


public class PreciseTimer extends EventDispatcher
{

private const INSPECT_TIME:int = 100;


private var _timer:Timer;
private var _startTime:int = 0;


private var _delay:int = 0;
private var _repeatCount:int = 0;
private var _continueForever:Boolean;


public function PreciseTimer(delay:int, repeatCount:int)
{

_delay = delay;
_repeatCount = repeatCount;
_continueForever = repeatCount <= 0;
init();

}


private function init():void
{

_timer = new Timer(INSPECT_TIME, 0);
_timer.addEventListener(TimerEvent.TIMER, onTimer);

}


public function start():void
{

_startTime = getTimer();
_timer.start();

}


public function stop():void
{

_timer.stop();

}


private function onTimer(event:TimerEvent):void
{

var timer:int = getTimer();
var durations:int = timer – _startTime;


if (durations > _delay)
{

if (_continueForever)
{

dispatchEvent(new TimerEvent(TimerEvent.TIMER));

}
else if (_repeatCount -- == 1)
{

stop();
dispatchEvent(new TimerEvent(TimerEvent.TIMER));
dispatchEvent(new TimerEvent(TimerEvent.TIMER_COMPLETE));

}
else
{

dispatchEvent(new TimerEvent(TimerEvent.TIMER));

}


_startTime = timer – ((durations – _delay))

}

}

}

}

So far, so good, here are the figures. For my purposes, this is close enough!

1093
2044
3069
4003
5025
6077
7044
8054
9002
10070
11116
12022
13040
14084
15003
16046
17049
18094
19020
20056

[AS3] Let’s LOOP FOR a WHILE, a short performance comparison over loops in Actionscript 3

Months ago someone pointed me at Joa Ebert’s wiki, which has a interesting category: Code Optimization. In this post I want to test some performance statements made in the loop article

I tested for and while loops with different data types (uint and int, Number is 4-5 times slower) and counting mechanisms (i++ or ++i), with and without accessing the counter variable. All loops had 268435455 (int.MAX_VALUE/8) iterations on my tripple core 2,1Ghz machine, 32bit WinXP, Flash player 10. The y-axis shows us the average time in milliseconds of at least 10 iterations. The highest and lowest value is not included.

AS3 Loop comparison

We can see that for is faster than while. Why? Well .. I just don’t know, if you have any idea, please leave a comment!

So the fasted two loops, nearly head to head, were:

//for uint i++
private function f1():void
{

var i:int = 0;

var n:int = int.MAX_VALUE/8;

for( i = 0; i < n; i++ ) { }

}

//for int ++i
private function f3():void
{

var i:int = 0;

var n:int = int.MAX_VALUE/8;

for( i = 0; i < n; ++i ) { }

}

 

Then I took a closer look on the for loops. Why is the ordinary loop with int as data type and i++ value increase slower?

AS3 for loops

 

What if the loop body is not empty and the value of the counter is needed? Well, here are the results. At this time 17895697 (int.MAX_VALUE/120) were enough.

AS3 for loops with access to counter var

Ok, now we are nearly at the same level, regardless of which data type or counting style is used. The only (negative) abnormality is the uint while, which is about 9% slower than the fastest loop.

Here we have the slow performer:

//while uint –n
private function f8():void
{

var i:uint = 0;

var n:uint = int.MAX_VALUE/120;

while( –n >= i )

{

n;

}

}

 

Conclusion: It’s totally up to you which loop you prefer (if you have to access the counter variable). For me I will continue to use the ordinary for loop, just like I ever did.