Loops!
October 3rd, 2008
I've been thinking about AS3 optimization lately so I dusted off the old benchmark code and started speed testing some things. I meant to put together a post filled with exciting optimizations and tricks, but I got bogged down almost immediately in loop code.
When I started getting into it, I was somewhat surprised by how many ways there are to write a basic for loop. Combined with the different number types, that grows into a huge amount of variation in the way people can write code, so it follows that some methods must be better than others. I broke it down into four different structures:
- Undefined variable, count up to ten.
- Variable set to 10, negative increment to zero.
- Variable set to 0, increment to ten.
- Variable set to 10, decrement to zero.

These results are a little odd…let's look at what's going on. First of all, the obvious one: int is fast, uint is slow, and untyped is downright painful. So int it is, now on to technique.
The first and third test appear to be the same code, but there's a pretty large discrepancy between them at runtime. In fact the first test always wins by a visible margin. The difference between the first technique and the other three, is that the first test doesn't need an extra trip to memory to manually assign value to the newly instanced variable.
You may also be wondering about the negative increment in the second test – this is actually two tricks in one (and for a long time, I believed this to be the fastest execution). Even using a negative value, the addition operator takes about ¾ the time of the decrement (j--) operator. On top of that, looping backwards from a high value to zero, means you don't need to run a comparison, you can just cast the variable directly to a boolean.
All the rest of the code should be pretty pedestrian. There is one little snag in the untyped results but I suspect that's coming from weirdness in the JIT when it has to continually recast those values, and it's worth noting that uint really doesn't like the increment/decrement operators. And lastly, if you're wondering, I didn't test while loops here because both while and for loops are compiled into the same code – as far as the player is concerned, there is no difference, so use whichever you prefer.
UPDATE: Ok this is borked. In the middle of the night it came to me (in a vision?) – since the variable is never defined in the first test, maybe the JIT is just jumping the rails and never going through that loop at all? That would certainly explain the speed increase (better than my feeble explanation earlier).
So testing should have been an easy iterator variable - testing a loop that counts to 10, over 1 million iterations should trace out 10 million. Somehow the undefined loop code is so extremely broken that it's actually leaking out into the scope above! When I tested I got back 10...implying that the test code actually broke my benchmark harness. I'm still trying to get to the bottom of this but in the meantime, just go with method #2.

February 11th, 2009 at 9:37 pm
I’d be curious to see how a while loop for the same thing would hold up:
var j:int = 11;
while (–j) {}
October 6th, 2009 at 8:51 am
Very interesting results. I did an article on inlining Math.ceil() just yesterday. I didn’t use a mod like you did, but instead compared:
int(value) == value
To check if value is a whole number. I’m seeing speedups of over 6x.
January 8th, 2010 at 11:05 am
I’ve seen an increase in speed in my for loops by doing the following:
increment before the i not after (e.g. ++i faster than i++)
go backwards:
for ( var i:int = 10 – 1; i >= 0; –i )
is faster than
for ( var i:int = 0; i < 10; ++i )
January 20th, 2010 at 12:14 pm
Mmm….how about:
var i:int=0;
for (i; i<10; i++)
for what I know (actual never test it) this is the fastest way.