This is the first step at creating something interesting with Apollo and Mii binary files. Others have been working on some cool apps including the MiiEditor and MiiMall, etc so you might ask.. why are you doing this?.. Like Michael Hedges said, "Because it's there"!
Actually there was a discussion the other day about integrating the Wii with online marketing and of course the idea came up of uploading and sharing your Mii character, so I thought it would be a great way to learn Apollo and do something fun at the same time.
Turns out, there's really nothing too Apolloish about this app other than reading in a file but you can imagine all the possibilities for it... Well I can't yet, so help me figure out how to use this ;)
The first step is to simply read in the binary file into some useful data structure so we can draw the character. Thanks to some help I got with bit masks and shifting, I got it working last night. My MiiParser takes a ByteArray and goes to work sorting out all the bits and bytes.
If you are interested in helping me work on this, let me know. I need a flash artist to create all the pieces so I can put bits to pixels. It would also be great to build a generic parser and a C-like struct in AS3 in order to do things more abstractly ( is that a word? ) like other languages have done for years.
You can get the code here. It was built with Flex Builder and Apollo although there's nothing flexy or apolloish about it really.... yet.
Also you can see the Mii data format here, another MiiEditor here and definitely check out the MiiMall.
Tuesday, March 20, 2007
Thursday, March 15, 2007
Array optimizations for AS3/AS2
Geoff sent out a great link for optimizing javascript code and I decided to run some tests with actionscript related to looping over arrays using ideas from the article. These tests produced some interesting results.
I ran several tests doing incremental loops and reversed loops against using "flipped" versions.
Flipped just means this:
var i:Number = array.length - 1;
do {
// something
} while( i--);
The obvious stuff first:
1. AS3 is waaay faster than AS2. Yay, we already knew that ;)
2. All the people that told you to declare the length outside the loop were right.
Now for the interesting stuff:
1. Reversing the loop is faster in all cases.
2. In AS3, using a standard reversed loop is faster than using the flipped version.
3. In AS2, using the flipped reverse version is faster than using the normal reversed version.
Now for something unexpected:
1. Declaring a re-used variable inside the loop was actually faster than declaring it outside the loop. Dunno bout that one, seemed counter intuitive to me. Will explore further.
When to use what:
1. It depends as always on what the inner loop is doing ;)
2. Run tests and implement the method that is faster for your implementation. Cmon, it doesn't take that long to do a couple tests and could dramatically improve performance depending on the situation.
Some helpful utils:
FDT TEMPLATE FOR REVERSE LOOP
var length:Number = ${array}.length - 1;
for (var ${index} : Number = length; ${index} >= 0; ${index}--)
{ ${cursor}
}
FDT TEMPLATE FOR REVERSE FLIPPED LOOP
var ${index}:Number = ${array}.length - 1;
do {
${cursor}
} while ( ${index}-- );
------------------------------------------------
Here's what I did. I setup four methods that basically loop through an array of integers and adds them up. Each method just changed slightly.
1. Normal forward loop without declaring the length outside the loop ( bad )
public function testNormalLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
for( var i:Number = 0; i < array.length; i++ ) {
var value:Number = array[i];
sum+= value;
}
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testNormalLoop1() " + elapsedTime);
}
2. Same as #1 but declare length outside the loop
3. Same as #2 but declare var value:Number; outside the loop
4. Same as #3 but get rid of value altogether and just say sum+= array[i];
--------------------------------------------------------------------------
5-8: Same as 1-4 but reverse the loop
--------------------------------------------------------------------------
9-12: Same as 1-4 but use the flipped version. 10-12 calcuate the length outside the loop.
public function testFlippedLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
var i:Number = 0;
do {
i++;
var value:Number = array[i];
sum+= value;
} while ( i < array.length );
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testFlippedLoop1() " + elapsedTime);
}
------------------------------------------------------------------------
13-16: Same as 9-12 but reverse the loop.
------------------------------------------------------------------------
17-20: Same as 13-16 but decrement in the while section.
public function testAltFlippedReversedLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
var i:Number = array.length -1;
do {
var value:Number = array[i];
sum+= value;
} while (i-- );
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testAltFlippedReversedLoop1() " + elapsedTime);
}
------------------------------------------------------------------------
My Results:
Testing array with length: 1000000
-----------------------------------------------
AS3
----------------------------------------------
testNormalLoop1() 313
testNormalLoop2() 219
testNormalLoop3() 218
testNormalLoop4() 438
testNormalReversedLoop1() 219
testNormalReversedLoop2() 203
testNormalReversedLoop3() 203
testNormalReversedLoop4() 406
testFlippedLoop1() 781
testFlippedLoop2() 563
testFlippedLoop3() 265
testFlippedLoop4() 547
testFlippedReversedLoop1() 609
testFlippedReversedLoop2() 594
testFlippedReversedLoop3() 250
testFlippedReversedLoop4() 562
testAltFlippedReversedLoop1() 547
testAltFlippedReversedLoop2() 547
testAltFlippedReversedLoop3() 219
testAltFlippedReversedLoop4() 453
-----------------------------------------------
AS2
-----------------------------------------------
testNormalLoop1() 1390
testNormalLoop2() 1172
testNormalLoop3() 1188
testNormalLoop4() 1265
testNormalReversedLoop1() 1266
testNormalReversedLoop2() 1250
testNormalReversedLoop3() 1265
testNormalReversedLoop4() 1297
testFlippedLoop1() 1328
testFlippedLoop2() 1109
testFlippedLoop3() 1125
testFlippedLoop4() 1219
testFlippedReversedLoop1() 1359
testFlippedReversedLoop2() 1188
testFlippedReversedLoop3() 1187
testFlippedReversedLoop4() 1266
testAltFlippedReversedLoop1() 1063
testAltFlippedReversedLoop2() 1062
testAltFlippedReversedLoop3() 1063
testAltFlippedReversedLoop4() 1140
I ran several tests doing incremental loops and reversed loops against using "flipped" versions.
Flipped just means this:
var i:Number = array.length - 1;
do {
// something
} while( i--);
The obvious stuff first:
1. AS3 is waaay faster than AS2. Yay, we already knew that ;)
2. All the people that told you to declare the length outside the loop were right.
Now for the interesting stuff:
1. Reversing the loop is faster in all cases.
2. In AS3, using a standard reversed loop is faster than using the flipped version.
3. In AS2, using the flipped reverse version is faster than using the normal reversed version.
Now for something unexpected:
1. Declaring a re-used variable inside the loop was actually faster than declaring it outside the loop. Dunno bout that one, seemed counter intuitive to me. Will explore further.
When to use what:
1. It depends as always on what the inner loop is doing ;)
2. Run tests and implement the method that is faster for your implementation. Cmon, it doesn't take that long to do a couple tests and could dramatically improve performance depending on the situation.
Some helpful utils:
FDT TEMPLATE FOR REVERSE LOOP
var length:Number = ${array}.length - 1;
for (var ${index} : Number = length; ${index} >= 0; ${index}--)
{ ${cursor}
}
FDT TEMPLATE FOR REVERSE FLIPPED LOOP
var ${index}:Number = ${array}.length - 1;
do {
${cursor}
} while ( ${index}-- );
------------------------------------------------
Here's what I did. I setup four methods that basically loop through an array of integers and adds them up. Each method just changed slightly.
1. Normal forward loop without declaring the length outside the loop ( bad )
public function testNormalLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
for( var i:Number = 0; i < array.length; i++ ) {
var value:Number = array[i];
sum+= value;
}
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testNormalLoop1() " + elapsedTime);
}
2. Same as #1 but declare length outside the loop
3. Same as #2 but declare var value:Number; outside the loop
4. Same as #3 but get rid of value altogether and just say sum+= array[i];
--------------------------------------------------------------------------
5-8: Same as 1-4 but reverse the loop
--------------------------------------------------------------------------
9-12: Same as 1-4 but use the flipped version. 10-12 calcuate the length outside the loop.
public function testFlippedLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
var i:Number = 0;
do {
i++;
var value:Number = array[i];
sum+= value;
} while ( i < array.length );
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testFlippedLoop1() " + elapsedTime);
}
------------------------------------------------------------------------
13-16: Same as 9-12 but reverse the loop.
------------------------------------------------------------------------
17-20: Same as 13-16 but decrement in the while section.
public function testAltFlippedReversedLoop1(array:Array) :Void {
var startTime:Number = (new Date()).getTime();
var sum:Number = 0;
var i:Number = array.length -1;
do {
var value:Number = array[i];
sum+= value;
} while (i-- );
var elapsedTime:Number = (new Date()).getTime() - startTime;
trace("testAltFlippedReversedLoop1() " + elapsedTime);
}
------------------------------------------------------------------------
My Results:
Testing array with length: 1000000
-----------------------------------------------
AS3
----------------------------------------------
testNormalLoop1() 313
testNormalLoop2() 219
testNormalLoop3() 218
testNormalLoop4() 438
testNormalReversedLoop1() 219
testNormalReversedLoop2() 203
testNormalReversedLoop3() 203
testNormalReversedLoop4() 406
testFlippedLoop1() 781
testFlippedLoop2() 563
testFlippedLoop3() 265
testFlippedLoop4() 547
testFlippedReversedLoop1() 609
testFlippedReversedLoop2() 594
testFlippedReversedLoop3() 250
testFlippedReversedLoop4() 562
testAltFlippedReversedLoop1() 547
testAltFlippedReversedLoop2() 547
testAltFlippedReversedLoop3() 219
testAltFlippedReversedLoop4() 453
-----------------------------------------------
AS2
-----------------------------------------------
testNormalLoop1() 1390
testNormalLoop2() 1172
testNormalLoop3() 1188
testNormalLoop4() 1265
testNormalReversedLoop1() 1266
testNormalReversedLoop2() 1250
testNormalReversedLoop3() 1265
testNormalReversedLoop4() 1297
testFlippedLoop1() 1328
testFlippedLoop2() 1109
testFlippedLoop3() 1125
testFlippedLoop4() 1219
testFlippedReversedLoop1() 1359
testFlippedReversedLoop2() 1188
testFlippedReversedLoop3() 1187
testFlippedReversedLoop4() 1266
testAltFlippedReversedLoop1() 1063
testAltFlippedReversedLoop2() 1062
testAltFlippedReversedLoop3() 1063
testAltFlippedReversedLoop4() 1140
Subscribe to:
Posts (Atom)