Tips on how to write efficient AS3

Just 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.

AS3 Tween Engine – Tweensy (Preview)

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 utilizing 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.

You Tube Flash AS3 / AS2 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.

AS3 Example

Actionscript:
import com.FlashDynamix.services.YouTube;
import com.FlashDynamix.events.YouTubeEvent;
//
var yt:YouTube = new YouTube();
yt.APIKey = "WplekwLy_Nw";
function onLoaded(e:YouTubeEvent) {
switch (e.method) {
case YouTube.VIDEOSBYTAG :
try {
for each (var video:XML in data) {
trace(video.name() + " : " + video);
}
trace("Videos For Tag : " + e.request.tag + " : " + e.data.length());
} catch (evt:ArgumentError) {
trace("ERROR : No Videos For Tag");
}
}
}
//
yt.addEventListener(YouTubeEvent.COMPLETE, onLoaded);
yt.videosbyTag("Top Gear");

AS2 example

Actionscript:
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 all the features listed on the YouTube API documentation here http://www.youtube.com/dev_docs

Download the source here