AS3 Performance Optimizations
Summary, use linked lists instead of Array indexes for fastest performance in traversing collections.
http://blog.je2050.de/2007/06/06/lists-faster-than-array/
WiiFlash
So in a somewhat down mood (bug fixing..bleh), figured I'd spend some time on some cool project to get the fires burning again ![]()
I bought a few wiimotes a few weeks ago, after seen John Grden use them at his excellent Papervision talk, as he was using it to control his Papervision driven presentation (written in Papervision).
I was worried that the wiimote and wiiserver might not work with the Dell 820 laptop bluetooth wireless, as I've never used the bluetooth on the laptop with anything, and previous experiences with bluetooth pairing has occasionally be painful. But it was *very* easy to setup, about 8 minutes from download to running the example.
Download the wiiserver package from http://www.wiiflash.org, this will give you the windows server (no mac yet, sorry). the as3 libraries and 3 demo Fla's, that show graphically the 3 different type of controllers supported, wiimote, nunchuck and classic controller.
If the remotes are new, make sure they have batteries (2 AA's), via popping off the back and turning the unit on via the small red button *within* the battery compartment.
Then on the task bar right click, then select 'Add New Connection'
Just click next, you should see a few options like this showing the various bluetooth devices it doesn't have connections to, in this case the "Nintendo PVL-CNT-01" is the droid your looking for.
and after you click next the bluetooth icon should turn green and you'll see the following connections manager
and starting up the wiiflash server you should see a connected icon like in the above, you need to make sure the bluetooth connection is working prior to starting the wiiserver. Meaning, powerup wiicontroller (flashy blinky blue lights), make sure connection is established in the , then powerup wiiserver. The remote should begin buzzing...which is quite alarming if it's on metal/glass table and your not expecting it... with it's blue led corresponding to it's appropriate id. Then fire up one of the examples included in the zip, or if your brave right click over the wiiserver running in the taskbar and select "Control Mouse", which in my test did work but very shakey, and only when it was pointed at the ceiling, likely as I don't have a 'sensor bar'.
If you leave the wiimote for a bit, it will turn off, and the wiiserver will apparently think there's still a connection despite there not being one. So just repeat, the above.
Compiling AS2.0 Projects with mx.* dependencies in FlashDevelop Beta 3
FlashDevelop Beta3 comes bundled with MTASC, but it by default misses an important configuration option, so building projects with references to mx.* will complain, even with the -mx option set, like:
characters 8-25 : type error class not found : mx.controls.Button
You'll need to add the following to the classpath (preferably global):
C:\Program Files\Adobe\Adobe Flash CS3\en\First Run\Classes
One trick to editing it in FlashDevelop since the file selector doesn't allow you to paste it in directly, opening up a windows Explorer window while the file dialog is open, and pasting the above into the address bar, a neat trick of windows is all windows are listening to the same events, so it will take the FlashDevelop tree browser to the correct spot.
SEO with Flash
Iconara has a great post on SEO with Flash/Flex centric sites.
Sadly in many rush-rush design centric projects, web considerations are late in the development cycle, such as user experience during preloading (this has affected about 80% of the projects I've been apart of), and SEO. Tacking these features on after the fact is prohibitively expensive.
Part of the problem, is intrinsic to the high pressure, creative first, engineering second, testing/deployement only if time permits..of those who develop flash content, being first tier largely designers concerned with experience (pixels, movement, colors), they will embed fonts, or photoshop them to get the right Typography. so even if they could be straight pages easily indexable, and bots could open up the swf to see inside (which they can do, see them, after it's been ran through a dozen photoshop filters, collaged with a dozen , and spraypainted while it will look spectacular...you might as well be giving the bot a captchas.
Even engineering probably is more concerned about how to get it to work during development, than introducing another asset to load, and attaching links dynamically, as it's one more thing to go wrong and have to be tested. Though if considered early, a loadVars or an XML file for key value pairs, isn't particularly hard to load/parse, Danny has a simple utility to help for precisely http://www.communitymx.com/abstract.cfm?cid=C45CA,
Google can and does index swfs, but it's rare that the links are actually relelvant. Frequentlly when building data driven Flash, if there are a 100 products and links to follow e.g. www.amazon.com/buyme?product.id=2, the link will be normalized into ' www.amazon.com/buyme?product.id' and '2'., with a string replace e.g.
function onClick (){
linkURL = SITE +"/" + SECTION +"?" + product.id;
}
When past projects have faced this, we used XML as the data and do client detection via a jsp/asp/etc +XLST and render HTML or Flash as appropriate.
Introduction to ActiveFrame, Cogs, Chain, Score, Sketch, fXperience
Intro to StateMachines
![]()
The good news is if your in team development, you've been diagramming them for years, as flowcharts and bubble diagrams. Bubbles are states, arrows are transitions. This is one of the keys to their usefulness in teams. The diagrams can be understood and modified by anybody, and can represent anything from a users interaction with the whole application, a game's AI, or the graphical transitions in a button rollover. Any Animator who has done keyframes and tweens knows has been unwittingly using states and transitions, but what about developers?
Most any application developer is familiar with OOP, and many design patterns like the State Pattern. Some may have heard of the term finite state machine (FSM) with a possible vague understanding of what one is/does, most are probably not familiar with Hierarchical state machines (HSM), which are especially powerful, especially in experience driven, Flash
and AIR content working with asynchorous network requests, and large media upload/downloads, long timeline, all of which have complicated life cycles with asynchronous call/callback.
I started using them in projects after first learning about them in software from Jonathan Kaye. After using a few different versions in a few different projects, and developing my own, I have been on a quest to spread the word ever since. OOP and SM's foundational aspects. They are orthogonal and complimentary, OOP describes the nouns of the system StateMachines's the behavior over time. An example the cat is meowing, cat is the noun, meowing is the current state, and it will change over time.
Intro to Cogs
Cogs is the AS3 library of statemachines, and common patterns that people can extend/plugin similar to how people reuse design patterns, to avoid reinventing the wheel. Just as in Design patterns, there are fundamental patterns, from simple toggleable button, to synchronized media players.
It's named Cogs first after the tiny teeth that compose gears, that when meshing properly make up engines which power most the mechanical world, and secondly Cognition as the meshing of neurons make up the engines of intelligence. Cogs primary use is increasing the intelligence of components, games, game AI, and applications, by several approaches:
Cogs allows you to ask where you are, where you can go, and automate chains of execution between two states. Often event driven components are black box event generators, identical events broadcast at different times mean completely different things (like NetConnection) this is far from simple.
The FSM and HSM are based on Miro Samek's approach of using functions instead of classes to represent states, this very low level implementation has several advantages, one of the first is being less code to understand and write. It also enables behavioral inheritance, similar to. Cogs is different in several ways from Miro's inspiring work in his book. First all possible transitions are supported instead of just the common ones, and are validated by the unit tests..and the testing framework itself being an FSM and supporting Asynchronous testing easily.
Ongoing I'm working on API's for deep history, serialization/deserialization a graphical visualizer, among other things.
ActiveFrame
Cogs is part/foundation of a larger framework named ActiveFrame. Which strives reduce commmon architectural decays, largely by decoupling.
- A message bus enabling event decoupling,
- Java Spring 'Dependency Injection' for Implementor Interface decoupling,
- plus a decoupling of the UI and controller..which can live in completely different swfs, similar to AS2.0's Object registerClass.
It's reasonably small for all these features, allowing it to be used for components, games, game AI or full blown applications.Sketch
is the visual extension of the Cogs, to deal with the View/UI world (e.g. movieclips/timelines, sprites), common layout, and UI/controller decoupling communication. While Sketch can be used whereever Flash can go, it's strong points are design and script heavy projects, in teams that have strong separations between design and scripting... they don't even have to be working on the same file.
Since it's based on Cogs, it's very easy to prototype and if flow diagrams (state diagrams) are used in the IA and Creative phases, it can act as a common language between design, IA, and engineering, as diagrams can easily be translated to code and back, and reworked easily. It supports what I call "introspectable UI's", in that the statemachine can act as the model, and summarize all the active states supported options to generate an appropriate "where can I go from here" UI.
Chain
is the workflow component, it's coordinates dependent parallel and sequential and nested tasks, with asynchrous call/callbacks, providing status along the way. Some uses for this are preloading assets, playlists, unit testing, easing and tweens, build out and tear down of UI's.
Score
is the the parallel timeline orchestration component, similar to a Orchestral score for coordinating multiple instances with a single virtual playhead. Useful for overlapping events. It's similar to an actionscript version of the Flash IDE timeline.
fXperience
is the visual components library. This is based off Cogs/Sketch, components have a wider lifecycle than those built into Flash and Flex., e.g. a button transitioning in, transitioning to up, transitioning to over etc. They support easy and iteratible skinning, so projects can start out simply as a graphic than graduate to more complicated ones as need requires.
Misc
All are a part of the TroyWorks AS3 code library that is MIT licensed on google (but isn't finished/uploaded yet, API isn't stable) There are many other useful utilities, datastructures and components of interest I'll be covering in more detail as they get more fully flushed out and converted to AS3 from AS2, I'm trying to make sure I don't add something already in AS3, and take full advantage of AS3's architecture.
Tools: FDT + Eclipse vrs FlashDevelop
So after another round of flux in my development environment, I resorted to using Eclipse (for coding) AND FlashDevelop (for compiling and quick projects) in tandem (along with SOS for trace debugging). Talk about a lot of desktop space!
This is because FDT+Eclipse, my favorite tool for ActionScript development is still in Beta (still a great code editor!) and in general building requires Ant tasks in Eclipse, which doesn't support the Flex Compiler Shell (huge speed increases), while FlashDevelop is an good editor, but has great compiler support.
About 2 months ago, with significant trepidation. I finally bit the bullet and made the move to AS3. It's been about 2 pretty turbulent months since. Learning the IDE of 2 major tools (Flash CS3, Flex 3.0 beta ), the massive syntax changes, new workflow, starting to get large libraries converted....breaking across the rocks of different paradigms.   Then midway the Flex beta license ran out (30 days is after all reasonable),. It wasn't worth it spending $300-$500 for a license to FlexBuilder 2.0 to keep going.
- I'm going to Max in October, I know 3.0 is out in a few months,
- The code editor is an order of magnitude weaker than FDT, and still quirky enough to make it unuseable at times in the beta, I guess some of my code does some tricky things which causes Flex's language parser to barf.
- I don't plan on using FlexBuilder/Flex on most of my projects...we aren't that data/standard control centric.
This created a window of no reasonable workflow. FlashCS3 does compile AS3 well (I first started having to use it with FlexBuilder 3.0, when running into quirks in it's parser). But the editor isn't much better than a plain text editor, for dealing with large libraries and components. So I started investigating other platforms, Sepy and FlashDevelop...etc. Which is about as motivating as looking at a bicycle after driving an F1,...but admittedly better than walking barefoot or standing still.   I was hoping that in my lack of paying attention that the years since I last reviewed would have some new releases, and while I didn't have time to investigate Sepy, I was pleased with FlashDevelop Beta 3. In a sunday afternoon I got from ground zero to building an AS2, and an AS3 project both using the Flash CS3, and separate the Mxmlc.exe, which nicely prompted me to look for the 'Flex Compiler Shell', which I hadn't heard of before.
http://labs.adobe.com/wiki/index.php/Flex_Compiler_Shell
The compiler shell is designed to startup once then talk with it, telling it to recompile files, typically by getting an id back on the first compile then recompiling. This can amount to huge timesavings. Once installed and incremental compiling is on, It's similar the speed jump to me from using Flash to using MTASC.
YAY!!!!
Incremental compiling has been high on my list of things I've been looking for out of AS3, Java has had this for almost a 8 years, and I grew to depend on it. Java is still way ahead...you can hot fix code running in the VM without restarting...while debugging, even remotely (if allowed)!.
FlashDevelop Beta 3 supports the Flex Compiler Shell without anything special, just drop in and go (very nice!). Sadly for Eclipse/Ant/FDT it won't work well, as the major performance increase is from not having to startup the mxmlc.exe everytime, but ant starts up and closes down as soon as it's finished, and there is no easy way to modify Ant/Eclipse to keep the process/dialog open. But since it's not terribly difficult to have both open, that's what I've done.
The biggest thing that I miss via this is the errors output by the compiler (both the syntax check, and full compile errors) show up in FlashDevelop, which clicking on lets you jump to, when I'd rather do it in Eclipse. Both tools are smart to watch for file changes, so it's possible to edit in both places. If a bit more UI to wrangle than idea;
Performance: Strict equality === versus compare by value ==
One of the cool features little used in actionscript is the strict equality operator '===' what this does is evaluate if two pointers endup at the same address in memory, rather than the contents of that address. This is similar to the performance increase of looking at the mailing address on two envelopes rather than actually going to the address, knocking on the door to see who lives there. But this only works for pass by reference (Object) vrs pass value types (e.g. int, uint, boolean) and during comparions those that don't compare by value (e.g. Number, String).
Coding wise, I also like switch statements, they are clean visually and semantically, and AS3 has the neat feature to allow any type to act as a switch value, other languages like Java/.Net restrict case statements to primitives numbers, or strings.
I created a class to test raw performance of different types/approaches used in switch statements, primarily to determine whether strings (as passed by event e.g. Event.type), numbers or signals (as done by cogs) is faster approach, and if switch statements could use strict equality or by value.
Full Fledged Classes used as the case statement and switch are the fastest at close to 1/3 the time. This is great as it offers author time compile checking, strong typing at runtime. Lookups are likely by identity (===) instead of by value (==) as in data types even when those are marked static and constant, which means performance is about twice that of using a value comparison, in addition, since they are fullfledged objects they can contain all sorts of things (e.g. toString, operations).
Downside is that no numerical id is attached by number by default, so it's harder to index and later lookup these values when they exist in a random collection of some sort, but since it's a full fledged object, adding an id variable is easy.
In the class containing the switch, e.g.
//277ms for 100K
switch(stringVal){
case JanuaryStaticConst:
case "January":
break;
}
//177ms for 100K
switch(intVal){
case 22:
break;
}
//166 ms for 100K iterations
switch(objRef){
case Class.StaticVal:
break;
}
//98 ms for 100K iterations
static const var StaticVal = Class.StaticVal;
switch(objRef){
case StaticVal:
break;
}
Flash's compiler doesn't replace Class.StaticVal, with StaticVal so there is a lookup overhead. So it's recommended that you capture a reference in a static const (see recommendations at end)
For primitive data types (String, number, int, etc), strings are about 70% slower than any numbers, potentially the length of
the string may also impact the performance (not tested). Note that even making the string a static const string offered
no performance increase (though probably a significant memory performance increase) because your using value comparison (==) in the switch statement
versus identity (===).
The fastest numerical type, was an typically an int though this wasn't really repeatable, or significant. But might
make sense to use if your using it as bitflag.
Test Results for 100K iterations:
SwitchNumber 177
switchInt 176
switchUInt 170
switchString 277
switchStringConst 275
switchIntConst 175
switchCogSignal 166 <-- lookup of CogSignal.SIGNAL
switchCogSignalB 97 <-- 'cached' CogSignal.SIGNAL pointer (set via static constructor)
switchSwitchSignal 98 <- declaring it internally
Recommendations:
1) use a custom class, static const on the class
e.g.
//cache the value during class/static initialization
public static const C_0:SwitchSignal = SwitchSignal.C_0;
and later
public function switchSwitchSignal(sig:SwitchSignal):void{
switch(sig){
case C_0: //SwitchSignal.C_0, but no lookup overhead.
2) for raw data types use int, instead of (uint, Number).
Java vers AS3 comparison
This Is a great overview of Java vers AS3 on a language feature level. In many cases I prefer AS3 over Java, method closure, anything for a switch type, strict equality === being some of my favorites.
Introspection in AS3: use of namespace
As I was mentioning in the last article, I was looking for ways to introspect code without resorting to use of 'public' access modifier /namespace.
This is for a particular project/framework named Cogs which I'll be covering more. Cogs is a statemachine, and allows for multiple active states, similar to putting animated movieclips inside other animated movieclips. Cogs uses functions in a very unique way, in that every function is a 'state' similar to a frame in Flash, and every state has events similar to 'enter_frame' and 'exit_frame'. A variable maintains a link to a current function, and passes events to it. So a Person class might have the following lifecycle, each state corresponding to a function.
- s_eating(evt:Event); //parent is s_awake
- s_awake(evt:Event); //parent is s_alive
- s_sleeping(evt:Event);
- s_alive(evt:Event);
- s_dead(evt:Event);
While Cogs has a reference to the current state (say eating), which bubbles events. If scoped to the public namespace, apps using Persons could inadvertently call other inactive states directly , causing undersired responses, when preferrably unauthorized calls to the function shouldn't compile at all.
Say if the person is currently in the 'dead' state, and someone asks "How are You?" Event/Request, it doesn't reply, but if they call s_awake, it might respond/trace "great!".Normally
Part of the problem somewhat unique to using Cogs's is validating the hierarchy making sure there are no dead ends. E.g. this is a good heirarchy.
- Root
- Dead
- Alive
- Sleeping
- Awake
- Eating
This would be a malformed one.
- Root
- Dead
- Alive
- Awake
- Sleeping
- Eating
flash.util.Proxy
So I was originally going down the path of using flash.util.Proxy's neat feature to 'iterate' over an object thinking it had special powers of visibilty with all it's capabilities of overriding iterators and the like. When actually it is just a Proxy, relaying requests to variables and methods frequently of child attributes/methods, other than itself.
Proxy in use should be composition primarily instead of inheritance. It's supposed to wrap other classes instead of be the class. This is kinda a way to achieve the appearance of multiple inheritance, via proxying requests to multiple classes. Anyway the for..in and describeType limitations still apply, there is nothing magical about the namespace/scope of Proxy or flash_proxy other than they aren't public so won't collide if methods are similarly spaced. However I noticed that tracing out methods namespaced to flash_proxy were showing up on the describeType. Which game me a clue to where to go.
AS3 namespace, creating, using.
The documentation on namespace in regards to AS3, and multiple classes is a bit hard to find. Especially on the web/google. But it's very cool (check the Flash CS3 help for examples)
starting here
http://livedocs.adobe.com/flash/9.0/main/flash_as3_programming.pdf
and here
Here's the basic steps to creating and using namespaces. Quote:
There are three basic steps to follow when using namespaces. First, you must define the
namespace using the namespace keyword. For example, the following code defines theversion1 namespace:
namespace version1;Second, you apply your namespace by using it instead of an access control specifier in a
property or method declaration. The following example places a function named
myFunction() into the version1 namespace:version1 function myFunction() {}
Third, once you’ve applied the namespace, you can reference it with the use directive or by
qualifying the name of an identifier with a namespace. The following example references the
myFunction() function through the use directive:use namespace version1;
myFunction();You can also use a qualified name to reference the myFunction() function, as the following
example shows:version1::myFunction();
What this doesn't cover is how to create namespaces, and URIs. The help documentation has two types of namespaces, that primarily used for XML and that used for actionscript visibility even though underlying they are probably the same thing. It took me an hour to figure out how to figure out how flash_proxy namespace was implemented, as that's not covered directly.
I created two folder/packages Test and Introspectable, Test containing the main executeable and Introspectable having a namespace, and a class that uses namespace to limit visibility for variables and such. My first goal was creating a namespace that is visible to multiple classes in multiple packages silmiar to flash_proxy, which was the trickiest part, as it's not a class. But rather AS3's somewhat unusual ability to import straight functions/etc. Similar to #include in AS2.
//FILE1: Introspectable/introspectable.as
package Introspectable {//note that default URIs are {package}.{namespace defined in this file}
//e.g. URI Introspectable.introspectable but I'm overriding it with URI of "com.troyworks.cogs"
public namespace introspectable = "com.troyworks.cogs";
}
//FILE2: Introspectable/
package Introspectable{
import Introspectable.introspectable;public dynamic class IntrospectableObj {
introspectable var introVar:Number= 0;
introspectable function s_introspectable():void{
trace("Hello World from introspectable::s_introspectable");
}
//File3: Test/Test_DescribeType.as
package Test {
import flash.display.Sprite;
import flash.utils.describeType;
// import Introspectable.*;
import Introspectable.IntrospectableObj;
import Introspectable.introspectable;public class Test_DescribeType extends Sprite{public function Test_DescribeType(){
super();
var intro:IntrospectableObj = new IntrospectableObj();
var desc:XML = describeType( intro);
trace("Test_DescribeType \r" + desc);
// use namespace introspectable;
intro.s_introspectable();
OUTPUT
note you can see the ones with the custom namespace in describe type, but since we haven't specified a namespace, calls will get an error 1006 'is not..'
TypeError: Error #1006: s_introspectable is not a function.
at Test::Test_DescribeType()[C:\DATA_SYNC\CodeProjects\Flash Work\as3 - introspection\Test;Test;DescribeType.as:28]
at [execute-queued]
Uncommenting the line
use namespace introspectable;
and running again allows the function to call successfully:
Test_DescribeType
variable name="introVar" type="Function" uri="com.troyworks.cogs"
method name="s_introspectable" declaredBy="Introspectable::IntrospectableObj" returnType="void" uri="com.troyworks.cogs"
Hello World from introspectable::s_introspectable
Which is the desired result of custom namespaced items that can be introspected and called but not without specifying the namespace up front.
Introspection in AS3
One of my design philosophies is leveraging technology to help create better technology. In design, this means using introspection to help validate the design elements, and autocreate classes. In coding this involves using introspection to help generate unit tests, and do class validation when you're doing things like function pointers, linked lists, static initialization.
One of the recent projects/framework named Cogs, a state machine (to be discussed more in future posts), uses function pointers extensively. So I use introspection to get the names dynamically of the states and validate the hierarchy, so coders can focus on developing the application instead of housekeeping. In languages in Java, introspection is quite powerful. In flash I was excited to see the potential of describeType(), which outputs an XML describing the class/instance.
Unfortunately in practice it's been limiting, introspection sees have to be marked as 'public' as anything else isn't visible. In particular protected and custom namespaces can't be introspected, even within the same namespace. Meaning a class can't introspect itself, even though it has access to the private/protected members of itself via normal code, or it's children, or utilities in the same package. This means custom namespaces and protected in regards to don't work like they do with variables, or functions.
This sucks. for-in is now limited to things on the prototype chain or plain objects, which are probably empty if your using standard classes. With describeTypes limitations seems crippled, limiting it's usefulness except for all but the simplest data types, or specifying everything by hand which is brittle.
