Recently I finished coding a game and all ran smooth on my iMac 3Ghz but then I tested it on a 2.6Ghz macbook and I noticed the movement of the player was not as smooth and even jumped here and there so I started thinking about optimization and how it is so much more important in games then websites or applications.

While searching for answers and tips about problems with actionscript3 and how to optimize it I ran into several good articles and comments so I thought it would be a good idea to make a post compiling all of them and also showing a summary of the most important topics.

First of all, if you’re using the AS port of Box2D previous to version 2.1 you might want to consider a few times to optimize it or downloading the new version (I heard it had some optimization done but not all code will be compatible by the way). One of those where I really saw a big difference was the number of calls that Box2D.Common.Math receives just to calculate max and min. Use Find and Replace on the Box2D classes to locate b2Max and b2Min calls and then replace them for inline calculation which is nothing more then a simple (a > b) ? a : b; and (a < b) ? a : b;

But anyway lets get on with AS3 optimization in general, keep in mind that some of these tips might be more or less important depending on which version of the player you have, if its the debugger player, in what environment you test it (Flash IDE, Standalone, Browser) and under which Operating System but most should remain true.

For these tests I’ll be using Flash Player 10.1.52.14 version running in MacOs X 10.6, I won’t be doing the code tests myself (no need to re-invent the wheel) but rather the Grant Skinner’s Quick as a Flash set of tests so you can see a summary here but full free to test them yourself, specially because there’s a lot more stuff in there then what I will test here.

Literal Values vs. Calculation

var a:uint = b + (1024 - 200) / 2;

Firefox: 19ms
Safari: 20ms
Standalone: 19ms

var a:uint = b + 412;

Firefox: 19ms
Safari: 19ms
Standalone 19ms

Formulas used to be a lot slower then literal values but my results show the same performance, maybe in more complex calculations still applies. Note that I’m not using a lot of variables in the calculations and both use “b” instead of its value, otherwise results could be different.

Multiplication vs. Division

result = num / 4;

Firefox: 31ms
Safari: 35ms
Standalone: 33ms

result = num * 0.25;

Firefox: 32ms
Safari: 35ms
Standalone: 32ms

For a long time it was a written rule that multiplication is faster than division (mostly because this is due to the way processors work), and well… it still is but the difference is not what is used to be and in some cases its the other way around. As a good practice and for the time being I still use multiplications instead of divisions whenever possible.

Strongest Typing

var pt:Object = {x: x, y: y};

Firefox: 84ms
Safari: 61ms
Standalone: 61ms

var pt:Point = new Point(x, y);

Firefox: 16ms
Safari: 15ms
Standalone: 17ms

As you can see its a good idea to use the right type for your variables.

Type Casting

var pt:Point = points[i] as Point;

Firefox: 69ms
Safari: 71ms
Standalone: 68ms

var pt:Point = Point(points[i]);

Firefox: 41ms
Safari: 42ms
Standalone: 40ms

var pt:Point = points[i];

Firefox: 14ms
Safari: 16ms
Standalone: 14ms

Whenever possible use implicit type casting. However there’s an exception in the case of iterators:

pt = points[(i * 2) as uint];

Firefox: 145ms
Safari: 159ms
Standalone: 165ms

pt = points[uint(1 * 2)];

Firefox: 105ms
Safari: 120ms
Standalone: 121ms

pt = points[i * 2];

Firefox: 123ms
Safari: 135ms
Standalone: 141ms

Conditional priority

if (expensiveTest() &amp;&amp; usuallyFalse)

Firefox: 69ms
Safari: 70ms
Standalone: 72ms

if (usuallyFalse &amp;&amp; expensiveTest())

Firefox: 4ms
Safari: 4ms
Standalone: 3ms

Sometimes this is hard to keep in mind when you’re coding but there’s a really good gain in it.

Function Call vs. Inline

Avoiding function calls when you can do inline code might result in up to 3 times faster execution.

Anonymous Function

Whenever possible avoid these at all cost, they can be up to 100 times slower but here we can see some interesting results depending on where we run the code:

Firefox

anonymous: 281ms
anonymousRef: 3ms
method: 0ms
reference: 2ms

Safari

anonymous: 82ms
anonymousRef: 3ms
method: 1ms
reference: 2ms

Standalone

anonymous: 100ms
anonymousRef: 2ms
method: 1ms
reference: 2ms

Loop invariant

for (var i:int = 0; i &lt; arr.length; i++)

Firefox: 105ms
Safari: 108ms
Standalone: 109ms

var len:int = arr.length;
for (var i:int = 0; i &lt; len; i++)

Firefox: 17ms
Safari: 18ms
Standalone: 17ms

This is one that is also useful to start forcing yourself to use.

Event vs. Callback

Event

Firefox: 80ms
Safari: 79ms
Standalone: 75ms

Callback

Firefox: 3ms
Safari: 3ms
Standalone: 2ms

This one really sucks because AS3 is all about Events but they’re usually a lot slower then callbacks.

Variable scope

literal: 3ms
local: 3ms
instance: 3ms
static: 3ms
class: 9ms

There’s not as much difference as it used to but class properties are still slower.

List types

construction and population

array: 113ms
arrayFixed: 107ms
vector: 64ms
vectorFixed: 19ms
linkedList: 457ms

iteration

array: 0ms
vector: 1ms
linkedList: 1ms
dictionary: 7ms
hash: 23ms

splicing and deleting

array: 213ms
vector: 2390ms
linkedList: 0ms
dictionary: 13ms
hash: 7ms

Whenever possible set to null instead of splicing arrays and vectors.

Array and Vector population

arrayOrVector.push(value);

Firefox: 73ms
Safari: 94ms
Standalone: 73ms

arrayOrVector[arrayOrVector.length] = value;

Firefox: 55ms
Safari: 73ms
Standalone: 53ms

arrayOrVector[i] = value;

Firefox: 12ms
Safari: 12ms
Standalone: 11ms

Here’s some links you might find useful:

Grant Skinner’s Quick as a Flash
A lot of AS3 performance tests
Case Study : ActionScript 3 Performance Optimization