Tips on how to write efficient AS3

robot-calculatorJust recently I have needed an in depth understanding of AS3 efficiency practises, so I figured this is easiest done by getting involved in a series of relevant tests. Though there are similar blog posts regarding this most have been focused on either loops or Number types and this article won't repeat these tests as I too discovered similar suggestions.

Here are my tests :

Array & Object constructing

new Array() and new Object() are about 3 times slower than [] and {}. Though further to this [] is much slower than [].concat() so if you have a constant reference to an empty Array use [].concat().

Index Number type for Arrays

In AS2 list[int(0)] was faster than list[0] this is no longer the true. list[0] is now the faster option. list[int(0)] is now faster than list[0]!

Create Array vs. Updating Array

If you can avoid it don't constantly create Arrays/Objects this is especially the case in long loops rather create them once then update.

Nulling Array vs. Splicing Array

When working with large Arrays splicing is obviously an expensive operation, you can avoid this by nulling the index and skipping it in a null scenario. If you need to splice in order to keep the Array length low. Then store these nulled indexes in another trash Array once the garbage count has reached a limit you've defined loop through the numerically sorted trash indexes deleting splices in bulk. This concept is demonstrated in Tweensy.

Nulling Object vs. Delete Object

Deleting an item in an Object is always more extensive than nulling it. If you're using a Dictionary try to use weak references in that case once the key is dereferenced the Flash garbage collector will eventually remove the item from the Dictionary.

Nesting Loops

Nesting loops is always slower try to minimize your nest depth to no more than 2. As well always use for loops if you can they are the fastest.

Inline code vs. function references

When executing a function it's more expensive if you call other functions within it, so if the function is an enterframe function or long loop try to minimize referencing alot of functions for best performance.

Arguments vs. variable referencing

Arguments in functions are slower than a reference to an objects variables so try to minimize the number of arguments you use.

Function apply scoping do it or not?

Scoping function.apply is a little bit slower than not so if you don't have to then don't.

Continue onto part 2

AS3 Tween Engine – Tweensy (Preview)

Tweensy AS3 Tweening Engine

Dynamic tweening is really important to a Flash Developer, and when I was programming in AS2 my tweening library of choice was either FuseKit or the Zigo Engine. Since AS3 there have been a few options available:

  • Tweener
  • Tween Lite
  • Adobe's Tween
  • GTween
  • ASAP Tween
  • There have been many posts on how some are better in performance and features than others. Without going into detail, I rate them in the following order, from best to worst:
    1) TweenLite/Max
    2) Tweener
    3) GTween
    4) ASAP Tween
    5) Adobe Tween

    Even though there are 5 options above, the top 2 are the only ones I'd ever consider using. Even with this said, Tween Lite is good, but it's not a code library I'd prefer to use. If anyone cares to take a look through the source code, they’ll notice that it's not particularly clearly (well) written. Because of this, it's not exactly easy for a developer to extend Tween Lite/Max if they need to.

    Introducing Tweensy, my new tweening engine, which has been in use for the last 8 months on many of my commercial projects, which I'll supply to the community free of charge (although donations are appreciated). As I mentioned above, Tween Lite/Max and Tweener are really the only libraries I feel I need to compare my performance and feature benchmarking with, to prove that Tweensy will equal, or more usually surpass the performance and features of the existing options. I'll post these performance/feature comparison tests in my next post.

    More importantly than this, I think it's crucial that a new tweening engine should have its own unique point of difference. From my review of the above tweening engines, it is clear that they are built for a similar concept (property and motion tweening) and in a simplistic comparison they offer the same features with varying performance.

    Tweensy, however, offers these unique features:

    1) A Bitmap rendering feature allowing for Bitmap Effects not easily achieved from the Adobe filter set such as Directional Motion Blur, Liquid Theshold, Directional Displacement and Buldge/Skew Displacement.
    2) Particle Emitters to generate smoke, fire, abstract, and magical effects from your motion tweens.
    3) Vector shape Tweening
    4) Gradient Tweening

    Well enough of the introduction - I'll show you some examples of what I've been able to achieve by utilising some of the features above. I recommend that you install the Flash Player 10 beta to get the best FPS results.

    So Tweensy is intended to provide motion effects, but at its core is an extremely efficient property tweening engine. As the name suggests, Tweensy is also designed to be very easy and flexible to use, so here's the code of how I created the fire effect example above.

     
    import com.flashdynamix.effects.layers.DisplacementLayer;
    import com.flashdynamix.effects.*;
    import com.flashdynamix.effects.extras.Emittor;
     
     
     
    import flash.display.*;
    import flash.geom.ColorTransform;
    import flash.utils.getDefinitionByName;
     
    var tween:Tweensy = new Tweensy();
    var layer:DisplacementLayer = new DisplacementLayer(tween, 550, 400, 2, 2, BlendMode.NORMAL, 0.95, 1, -6, 1);
     
    // This makes the layer offset each of the colour channels on each render so the result is black smoke
    layer.ct.redOffset = -20;
    layer.ct.blueOffset = -20;
    layer.ct.greenOffset = -20;
     
    // This is the start colour for the fire
    var ct:ColorTransform = new ColorTransform(0, 0, 0, 1, 80, 30, 15);
     
    // This is the display asset which will be used to render the flame effect
    var Flame: Class = getDefinitionByName("Flame") as Class;
     
    var emittor:Emittor = new Emittor(tween, Flame, BlendMode.ADD, 2, 0.73, 0.77, 5, 60, 0.5, -45, 90);
    emittor.startColor = ct;
    emittor.startScale = 0.2;
    emittor.endScale = 2;
     
    addChild(layer);
     

    Now before someone comments, I do realise that this isn't exactly 1 line of code. This is intentional because Tweensy is designed not only for the examples I demonstrate (examples are just to show what can be done), but provides a library with which you can create your own motion effects. This makes Tweensy a lot of fun to experiment with.

    The source code to Tweensy is currently available as a public beta here. I am particularly interested in Flash developers who would like to get involved in creating their own motion effects examples to provide feedback and improve Tweensy. I hope to have a release version of Tweensy publicly available some in late October 2008 with a public beta available before then.

    Camera Class Quirks with FMS

    I did a project recently requiring a web camera recording to Flash Media Server 3. Whilst I was working on this I found out some interesting (annoying) things about the Camera class. These include :

    Tip 1.

    When initiating a connection to the Camera it's best to do this through the Microphone class. Sounds odd I know! The reason for this is when this code is called :

    var camera:Camera = Camera.getCamera();
    ns.attachCamera(camera);

    there's a hang just after the allow button is selected on the security dialog panel. This is rationalled in the Adobe Flash help as 'Scanning the hardware for cameras takes time'. So it's best to trigger the security panel via

    var microphone:Microphone = Microphone.getMicrophone();
    ns.attachAudio(microphone);

    then listen for the Status Event of UnMuted or later in your application call

    var camera:Camera = Camera.getCamera();
    ns.attachCamera(camera);

    There will always be a delay on this code ns.attachCamera(camera); but at least via activating the Microphone first you won't get a bug like delay of the security panel not disappearing immediately after the allow button is pressed.

    Tip 2.

    When recording to a Flash Media Server make sure the camera has activity via the Activity Status Event before publishing the stream. Otherwise you may get a static or black frame at the beginning of the recorded stream.

    Tip 3.

    To disable/turn off the Camera after a recording is complete do so via :

    ns.attachCamera(null);

    Though this is actually documented for AS3 it wasn't in AS2. Once this has been done the Camera will need to be reconnected for a new recording and users will experience this delay again as the Camera starts as mentioned above.

    Tip 4.

    When embedding your Flash do not change the wmode from default. Otherwise you will get problems on specific browser configurations i.e. Firefox PC . These problems include that the allow button on the security dialog box will not hide on click.

    Tip 5.

    When detecting wether the user has a web camera you can't rely on Camera.names.length(). This is because there are scenarios whereby devices will appear in the list which may not be webcameras but devices like TV capture cards and can not be used as a camera. The solution for this is when the camera is attached via

    var camera:Camera = Camera.getCamera();
    ns.attachCamera(camera);

    Then add a time out catch which can be cleared via the camera's activity event, so that if camera activity occurs within the time out of say 5 seconds then clear the timeout. Otherwise if the timeout happens handle the error scenario.

    Tip 6.

    Further to the above it's good at the point of displaying the error message to give the user an option to fix this problem. This is because it may simply be a matter of the user changing the default camera selected. This can be done via adding a button and firing the Camera devices security dialog by the following :

    Security.showSettings(SecurityPanel.CAMERA);

    It's interesting to know that when the user is selecting options from the Camera devices list it's possible to detect wether the option selected is actually a Camera. Once again this is done via camera.activityLevel>0 on the Camera's activity event. Sadly there is not yet a reliable way to detect when the dialog panel close event occurs. So with this in mind when the user has picked a camera, you should make a noticible visual change somewhere behind the dialog box (and overlay screen) so the user will proceed to the close button - happy days.

    Google, Windows, Yahoo, Ask Maps API for AS3/AS2/Flex

    It's been some time coming though I've finally had time to finish the AS3 build of my universal maps code. It's available for download free of charge (though donations are apreciated) from the same SVN repository and the details for this are below. As well included is the original AS2 version in the legacy.zip file.

    It's been a nice to re-build this project from scratch by taking full advantage of AS3 to simplify the original AS2 universal maps code as it's now 95 classes from over 500 but still offering almost all the inital functionality! As well not to mention the amazing performance differences between AVM1 and 2. I haven't gotten around to full documentation (will soon) but there are samples included on all the maps sources to easily get you started.

    Here are some examples...

    Google Maps

    Windows Virtual Earth Maps
    [kml_flashembed movie="http://www.flashdynamix.com/examples/Maps/SWFLoader.swf?url=WindowsMap.swf" height="512" width="512" base="http://www.flashdynamix.com/examples/Maps/" /]

    Google Mars Maps
    [kml_flashembed movie="http://www.flashdynamix.com/examples/Maps/SWFLoader.swf?url=GoogleMapMars.swf" height="512" width="512" base="http://www.flashdynamix.com/examples/Maps/" /]

    Google Moon Maps
    [kml_flashembed movie="http://www.flashdynamix.com/examples/Maps/SWFLoader.swf?url=GoogleMapMoon.swf" height="512" width="512" base="http://www.flashdynamix.com/examples/Maps/" /]

    Download the source from the following SVN details
    SVN: http://mapsas3.googlecode.com/svn/trunk/

    Don't have an SVN client? I recommend you use Tortoise - get it here or if you're an Eclipse user try Subclipse

    To compile with Flex I used the command line arguments on the GoogleMapFlex example class :
    -default-size 512 512 -default-frame-rate 31 -default-background-color 0x262B2D -library-path {flexSDK}/frameworks/locale/en_US -verbose-stacktraces
    To publish a different example using Flex just make sure the class extends UniMapFlex rather than UniMap and that's it.

    You Tube Flash AS3 / AS2 Data & Player API

    Recently I have been working on something involving the use of video content from You Tube. With the lack of a good API out there I created my own. Below is a simple example of this working with sample code to download further below.

    [kml_flashembed fid="youTube" name="youTube" movie="http://www.lostinactionscript.com/wp-content/swf/youTube.swf" base="/wp-content/swf/" width="700" height="460"]

    AS3 example

    import com.flashdynamix.services.YouTube;
    import com.flashdynamix.events.YouTubeEvent;
    //
    var yt:YouTube = new YouTube();
    yt.clientKey = "ytapi-ShaneMcCartney-flashdynamix-vuj2k916-0";
    function onLoaded(e:YouTubeEvent) {
    switch (e.method) {
    case YouTube.SEARCH :
    for each (var video:YouTubeVideo in e.data.list) {
    trace(video);
    }
    break;
    }
    }
    //
    yt.addEventListener(YouTubeEvent.COMPLETE, onLoaded);
    yt.videosForTag("Top Gear");

    AS2 example

    import com.FlashDynamix.services.YouTube;
    //
    var yt:YouTube = new YouTube();
    yt.APIKey = "WplekwLy_Nw";
    var obj:Object = new Object();
    obj.loaded = function(evt:EventArgs) {
    switch (evt.type) {
    case YouTube.VIDEOSBYTAG :
    var videos = evt.value.video;
    break;
    }
    };
    //
    yt.addListeners(obj);
    yt.videosbyTag("Top Gear");

    The class I created YouTube.as supports both the legacy and current version of the YouTube API legacy documentation and current documentation.

    Download the source from the following SVN details
    SVN: http://youtubeas3.googlecode.com/svn/trunk/

    Don't have an SVN client? I recommend you use Tortoise - get it here or if you're an Eclipse user try Subclipse




    Me

    I am Shane McCartney an Aussie Flash Developer who's currently working in London on a contractual basis. If you would like to check out some of the work I have done recently, go to my folio at shanemccartney.com.

    Donate

    If you find the source code or information provided on this site of such use that you would like to donate please do it is appreciated.

    Your donation will help us to provide even more source code to the community and cover the cost of time to develop and maintain the source code we provide, thank you.


    Meet me at

    FITC Toronto