Friday, November 13, 2009

three little tricks

Here are a couple of tricks I learned form this article:

I try never to access an array's length in a for loop:

for ( var i : int = 0; i < people.length; i++ ) ...

That's bad, because each time the loop iterates, it has to dig into people and access its length property. I get a boost in optimization (without losing clarity) by doing this:

var numPeople : int = people.length;
for ( var i : int = 0; i < numPeople; i++ ) ...

But I'm bothered by the fact that both i and numPeople are throw-away variables (just needed for loop mechanics), yet only one is declared outside the for statement. So here's the trick:

for ( var i : int = 0, numPeople = people.length; i < numPeople; i++ ) ...

I advocate either that or this:

var i : int = 0;
var numPeople : int = people.length;
for ( i; i < numPeople; i++ ) ...

Note: you could also write the for loop this way:

for ( ; i < numPeople ; i++ )...

Trick two:

Let's say you need to loop backwards through an array by index. You could do this:

var arr : Array = [ 10, 20, 30, 40, 50 ];
for ( var i : int = arr.length - 1; i <= 0; i-- )
{
trace( arr[ i ] );
}

//output: 50, 40, 30, 20, 10

or (here's the trick) you could just do this:

var arr : Array = [ 10, 20, 30, 40, 50 ];
var i : int = arr.length - 1;
while( i-- )
{
trace( arr[ i ] );
}

//output: 50, 40, 30, 20, 10

Why does that work? Won't i keep decrementing past zero (-1, -2, -3...)? No, because in the Boolean sense, zero reads as false (all other numbers read as true). So while( 0 ) will stop the loop.

One final trick:

I didn't learn this one from the article I liked to above. I've seen it in various places.

Let's say you want to either set a variable equal to a value read in from an xml file OR, if there is no value in the xml file, you want to set the variable to some default value. (Hint: note the word "or" in the previous sentence.)

Here's what I used to do:

if ( valueFromFile == null ) speed = valueFromFile;
else speed = 10;

or I might have done this:

speed = ( valueFromFile == null ) ? valueFromFile : 10;

or even this:

speed = ( valueFromFile ) ? valueFromFile : 10;

What I hate about all those versions is the stuttering of "valueFromFile." Via the trick, I can eliminate it like so:

speed = valueFromFile || 10;

I love how clean this looks, especially when you're using it with multiple values:

var speed : int = speedFromFile || 10;
var color : uint = colorFromFike || 0xFF00FF;
var name : String = nameFromFile || "George";

1 comment:

  1. Just a little quibble about the .length issue. It wasn't, as the article claims, something google figured out. That's been a known, albeit, in most cases, useless optimization for ages. Also, it's obvious from the google comments that the reason for it because the length "must be fixed during loop". So the only way to ensure the loop count remains constant throughout the duration of the loop is to assign the value to a local variable prior to beginning the loop. If there was even any optimization considerations, it was obviously secondary to that concurrency issue, since the optimization wasn't even mentioned in the code.

    ReplyDelete