Adobe AIR, Flash Player and SWF versions

List of all versions:

AIR Flash Player SWF
1.5 | 2.0 10.0 | 10.1 10
2.6 10.2 11
2.7 10.3 12
3.0 11.0 13
3.1 11.1 14
3.2 11.2 15
3.3 11.3 16
3.4 11.4 17
3.5 11.5 18
3.6 11.6 19
3.7 11.7 20
3.8 11.8 21
3.9 11.9 22
4.0 12 23
13 13 24
14 14 25
15 15 26

Compiler Arguments:

  • Flash Player: –target-player=11.7
  • SWF: -swf-version=20

Release Notes:

This post will get updates! 🙂

ActionScript performance test for Array, Object, Vector literals and Array.push, Vector.push methods

Yesterday a “tweet” pointed me to a nice article about ActionScript 3.0 optimization. Most of these techniques are quite common within the ActionScript developer scene but one thing caught my attention: A link to Jackson Dunstans blog post about runtime performance and the const and final keywords. Since I always tried to use at least final classes I was a little disappointed that my extra work time doesn’t have any performance benefit at runtime.

Due to that circumstance I was curious about some other common techniques like “Use Object and Array Literals Whenever Possible” or “Add Elements to the End of an Array Without Pushing”. I wanted to check performance benefits for myself just to make sure it’s worth the effort. So I wrote a little test script:

var result : String = "Test playerType: " + Capabilities.playerType + " version: " + Capabilities.version + "\n",
	i : int = 0,
	c : int = 1000000,
	array : Array,
	object : Object,
	vectorInt : Vector.<int>,
	startTime : int;
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { object = new Object(); }
result += c + " times: object = new Object()             -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { object = {}; }
result += c + " times: object = {}                       -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { array = new Array(); }
result += c + " times: array = new Array()               -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { array = []; }
result += c + " times: array = []                        -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { vectorInt = new Vector.<int>(); }
result += c + " times: vectorInt = new Vector.<int>()    -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { vectorInt = new <int>[]; }
result += c + " times: vectorInt = new <int>[]           -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { array.push( i ); }
result += c + " times: array.push( i )                   -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { array[ array.length ] = i; }
result += c + " times: array[ array.length ] = i         -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { vectorInt.push( i ); }
result += c + " times: vectorInt.push( i )               -> duration: " + String( getTimer() - startTime ) + "\n";
 
startTime = getTimer();
for ( i = 0; i < c; i++ ) { vectorInt[ vectorInt.length ] = i; }
result += c + " times: vectorInt[ vectorInt.length ] = i -> duration: " + String( getTimer() - startTime ) + "\n";
 
var textFormat : TextFormat = new TextFormat();
	textFormat.font = "Courier";
	textFormat.size = 14;
 
var textField : TextField = new TextField();
	textField.autoSize = TextFieldAutoSize.LEFT;
	textField.background = true;
	textField.backgroundColor = 0xFFFFFF;
	textField.defaultTextFormat = textFormat;
	textField.multiline = true;
	textField.text = result;
 
addChild( textField );

It turns out that the benefits differ greatly on platform and player type but basically it’s always a good idea to avoid using the .push methods and new keyword. While there’s almost no speed difference in Flash Players and Plug-ins, the debug versions are really slow. And check out the blazing fast object creation with AIR on iOS! Or is this a compiler optimization? Here my results:


Flash CS 5 publish
Test playerType: External version: MAC 10,1,52,14

1000000 times: object = new Object() -> duration: 246
1000000 times: object = {} -> duration: 427
1000000 times: array = new Array() -> duration: 1288
1000000 times: array = [] -> duration: 339
1000000 times: vectorInt = new Vector.() -> duration: 586
1000000 times: vectorInt = new [] -> duration: 596
1000000 times: array.push( i ) -> duration: 134
1000000 times: array[ array.length ] = i -> duration: 137
1000000 times: vectorInt.push( i ) -> duration: 113
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 114


Flash Player Debugger.app
Test playerType: StandAlone version: MAC 11,1,102,62

1000000 times: object = new Object() -> duration: 179
1000000 times: object = {} -> duration: 311
1000000 times: array = new Array() -> duration: 1072
1000000 times: array = [] -> duration: 313
1000000 times: vectorInt = new Vector.() -> duration: 397
1000000 times: vectorInt = new [] -> duration: 402
1000000 times: array.push( i ) -> duration: 118
1000000 times: array[ array.length ] = i -> duration: 108
1000000 times: vectorInt.push( i ) -> duration: 111
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 89


Flash Player.app
Test playerType: StandAlone version: MAC 11,1,102,62

1000000 times: object = new Object() -> duration: 127
1000000 times: object = {} -> duration: 183
1000000 times: array = new Array() -> duration: 227
1000000 times: array = [] -> duration: 189
1000000 times: vectorInt = new Vector.() -> duration: 215
1000000 times: vectorInt = new [] -> duration: 218
1000000 times: array.push( i ) -> duration: 72
1000000 times: array[ array.length ] = i -> duration: 62
1000000 times: vectorInt.push( i ) -> duration: 61
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 42


Browser Debug Plug-in (Safari)
Test playerType: PlugIn version: MAC 11,1,102,62

1000000 times: object = new Object() -> duration: 157
1000000 times: object = {} -> duration: 249
1000000 times: array = new Array() -> duration: 1015
1000000 times: array = [] -> duration: 293
1000000 times: vectorInt = new Vector.() -> duration: 281
1000000 times: vectorInt = new [] -> duration: 282
1000000 times: array.push( i ) -> duration: 124
1000000 times: array[ array.length ] = i -> duration: 117
1000000 times: vectorInt.push( i ) -> duration: 124
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 94


Browser Plug-in (Google Chrome)
Test playerType: PlugIn version: MAC 11,2,202,235

1000000 times: object = new Object() -> duration: 147
1000000 times: object = {} -> duration: 146
1000000 times: array = new Array() -> duration: 237
1000000 times: array = [] -> duration: 224
1000000 times: vectorInt = new Vector.() -> duration: 257
1000000 times: vectorInt = new [] -> duration: 266
1000000 times: array.push( i ) -> duration: 54
1000000 times: array[ array.length ] = i -> duration: 61
1000000 times: vectorInt.push( i ) -> duration: 70
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 51


AIR SDK 3.2
Test playerType: Desktop version: MAC 11,2,202,223

1000000 times: object = new Object() -> duration: 274
1000000 times: object = {} -> duration: 243
1000000 times: array = new Array() -> duration: 1344
1000000 times: array = [] -> duration: 379
1000000 times: vectorInt = new Vector.() -> duration: 431
1000000 times: vectorInt = new [] -> duration: 426
1000000 times: array.push( i ) -> duration: 135
1000000 times: array[ array.length ] = i -> duration: 136
1000000 times: vectorInt.push( i ) -> duration: 153
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 74


iOS (iPad 3) debug interpreter
Test playerType: StandAlone version: MAC 11,1,102,62

1000000 times: object = new Object() -> duration: 4707
1000000 times: object = {} -> duration: 2033
1000000 times: array = new Array() -> duration: 22191
1000000 times: array = [] -> duration: 2993
1000000 times: vectorInt = new Vector.() -> duration: 10235
1000000 times: vectorInt = new [] -> duration: 10156
1000000 times: array.push( i ) -> duration: 1728
1000000 times: array[ array.length ] = i -> duration: 1670
1000000 times: vectorInt.push( i ) -> duration: 2056
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 1951


iOS (iPad 3) ad-hoc
Test playerType: Desktop version: IOS 11,2,202,223

1000000 times: object = new Object() -> duration: 1224
1000000 times: object = {} -> duration: 0 !!!
1000000 times: array = new Array() -> duration: 5886
1000000 times: array = [] -> duration: 1048
1000000 times: vectorInt = new Vector.() -> duration: 2737
1000000 times: vectorInt = new [] -> duration: 2784
1000000 times: array.push( i ) -> duration: 2043
1000000 times: array[ array.length ] = i -> duration: 234
1000000 times: vectorInt.push( i ) -> duration: 1524
1000000 times: vectorInt[ vectorInt.length ] = i -> duration: 643

Always worth reading: http://gskinner.com/talks/quick/

Safari Flash Player detection problems with ClickToFlash

I really like the concept of blocking Flash, mainly because I don’t see these unwanted, crappy developed Flash adds sucking performance, but also because it’s a nice way to recognise Flash parts in websites. You’ll have your own reasons.

Safari is, except for testing purposes, my browser of choice, but I was having trouble on different websites accessing Flash content because the Flash plugin was not detected correctly. Since I had to update the Flash Player on my system again, I decided to figure out what the problem is.

According to Playerversion.com an older Flash Player version – MAC 10,0,45,0 – was found first, then the display switched to my installed Flash version – MAC 10,3,181,14 (Debug player).

I used the Flash Player Uninstaller but Flash Player version MAC 10,0,45,0 was still displayed in Safari.

After some research I figured out that ClickToFlash doesn’t display the correct Flash Player version and therefore doesn’t work in all Flash detection scripts. Just check Safari - Help - Installed Plugins and search for "Flash" and you’ll see that ClickToFlash simulates somehow an outdated Flash Player version (seems to be hardcoded).

So until ClickToFlash will be updated displaying the correct installed Flash Player version I’ll use AdBlock For Safari. More Flash but less problems – hopefully. 🙂

The Hitchhiker’s Guide to a Flash Player update

I really hate Flash Player updates just because it always takes me some time to figure out again how to update all of them on my Mac. Why isn’t there some kind of centralized Flash Player Manager?

Well, as normal user it’s really easy. Just visit Adobe and you’re almost done. But for me as developer I need to update all players used by Flash CS 5, Flash Builder 4 and the Flex SDKs as well. Note to myself: Just remember these steps (in this case for 10.2):

Visit the Flash Player Download Heaven.

Update Browser Debug Player:

  • “Download the Macintosh Flash Player X.X Plugin content debugger (Intel-based Macs)”
  • Run “Install Adobe Flash Player Debugger.app”.
  • Do nothing with Google Chrome! It updates automatically and will be your performance weapon of choice. It’s still running a release version of Flash Player. Really great if you use apps like http://audiotool.com/.

Update Adobe Flash CS 5 Release Projector for Mac OS X:

  • “Download the Macintosh Flash Player 10.2 Projector”
  • Save file as Applications/Adobe Flash CS 5/Players/Flash Player.app

Update Adobe Flash CS 5 Debug Projector for Mac OS X:

  • “Download the Macintosh Flash Player 10.2 Projector content debugger”
  • Save file as Applications/Adobe Flash CS 5/Players/Debug/Flash Player Debugger.app

Update Adobe Flash CS 5 Release Projector for Windows:

  • “Download the Windows Flash Player 10.2 Projector”
  • Save file as Applications/Adobe Flash CS 5/Players/FlashPlayer.exe

Update Adobe Flash CS 5 Debug Projector for Windows:

  • “Download the Windows Flash Player 10.2 Projector content debugger”
  • Save file as Applications/Adobe Flash CS 5/Players/Debug/FlashPlayerDebugger.exe

Well, there is one issue I don’t understand, but I think everything is working properly. I created a little file running this script:

import flash.system.Capabilities;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
 
var textField : TextField = new TextField();
	textField.autoSize = TextFieldAutoSize.LEFT;
	textField.text = Capabilities.version;
 
addChild( textField );

But when I’m just “testing” in Flash CS 5 it still says “MAC 10,1,52,14”. When I’m “debugging” it says “MAC 10,2,152,26”. I removed all Flash Player.app and Flash Player Debugger.app except the latest. If you have a clue – let me know.

Just for me – Flash Player Updates I manually installed lately:

  • 15.06.2011 – MAC 10,3,181,26

Flash Performance Visualizer

Mr.doop’s Hi-ReS! Stats is a must have for every ActionScript developer. Seems to be still no. 1!
And I don’t want to search again… So here just the links:

Mr.doop’s blog | Hi-ReS! Stats
Mr.doop’s Stats.as @ GitHub

Update – Most recent version I found:
http://code.google.com/p/mrdoob/source/browse/trunk/libs/net/hires/debug/Stats.as