• Nov
  • 30th
  • 2008

Why Statics in ActionScript 2.0 Are Slow

, ,

A couple of years ago I was tasked with developing a tween engine for Flash on the mobile platform. My aim was to support the usual Penner equations but also provide an optimized engine capable of running / managing multiple tweens simultaneously.

My design for the central class was pretty straightforward, with a single movieclip processing a list of live tweens and the standard functionality to run tweens on any property of a MovieClip, add callbacks, pause etc.

After I was done I started profiling (painful as it is in ActionScript 1.0/2.0) to discover any obvious bottlenecks. One of  the first things I noticed was the length of time a simple if/else if/else block was taking to process when constructing a tween.

if (easeDirection & Ease.IN)
....
else if (easeDirection & Ease.OUT)
....

I was somewhat puzzled and resorted to flasm‘ing the offending method to see what was going on under the hood. What I found surprised me to say the least.

When a static property is referenced its entire package chain is pushed onto the stack before it can be accessed.

So if you have a static property under the Ease class, Ease.IN and this sits in the package co.uk.mikestead.animate then co, uk, mikestead and animate (package chains are mirrored as objects under _global) are pushed onto the stack before the Ease class (type function) is pushed on, to get at IN. This occurs for every access, even if the same static property has been accessed previously within the same method.

Now this is not good, but if you’re accessing a single static property in your method then it’s a hit you can probably get away with (I’ll describe shortly how you can even minimize this). If however you are accessing one or more static properties of a class then here’s how you can reduce the overhead.

If you access one or more static properties of a class within a method then store a reference to the class at the start of the method and access the static properties through this.

By doing this the package chain is traversed just once each time the method is called, with the class then referenced through this variable for the life of the method execution.

To provide an example, and show how much of a performance gain this can make, I’ve put together a simple test movie with the following code.

import co.uk.mikestead.animate.Ease;

class StaticLookupSpeedTest
{
    /** Number of iterations per test */
    public var iterations:Number = 100000;
   
    /** Reference to Ease class */
    private var easeType:Function;

    /**
     * Class constructor.
     */

    public function StaticLookupSpeedTest()
    {
        easeType = Ease;
    }

    /**
     * Test the lookup speed of static properties of an external class.
     *
     * @return The execution time of this test in milliseconds
     */

    public function testStaticLookup():Number
    {
        var i:Number = iterations;
        var t:Number;
        var time:Number = getTimer();
        while (i--)
        {
            t = Ease.EASE_IN;
            t = Ease.EASE_OUT;
        }
        return getTimer() - time;
    }

    /**
     * Test the lookup speed of static properties of an external
     * class which is referenced locally in a method.
     *
     * @return The execution time of this test in milliseconds
     */

    public function testStaticLookupMethodLevel():Number
    {
        var ease:Function = Ease;
        var i:Number = iterations;
        var t:Number;
        var time:Number = getTimer();
        while (i--)
        {
            t = ease.EASE_IN;
            t = ease.EASE_OUT;
        }
        return getTimer() - time;
    }

    /**
     * Test the lookup speed of static properties of an external
     * class which is referenced locally from class level field.
     *
     * @return The execution time of this test in milliseconds
     */

    public function testStaticLookupClassLevel():Number
    {
        var i:Number = iterations;
        var t:Number;
        var time:Number = getTimer();
        while (i--)
        {
            t = easeType.EASE_IN;
            t = easeType.EASE_OUT;
        }
        return getTimer() - time;
    }
}

And here’s the results of the first two tests run under Flash Player 9.

  • External static prop lookup: 694ms
  • Static prop lookup through class reference in method: 140ms

And with Flash Lite 2.1 under the Sony Ericsson W51S emulator.

  • External static prop lookup: 1208ms
  • Static prop lookup through class reference in method: 264ms

In both tests the local ref provides a 4.5+ speed increase.

You may be thinking this is no big deal, but if you have many references to static properties scattered around your application then this can add up significantly.

As I mentioned earlier, there’s a way to optimize even the package traversal at the start of a method, and you may have noticed it from the third and final test in the class.

If you access one or more static properties throughout a class (even static properties of the class you’re in!) you should store a reference to this class as a field and use it to access those same static properties within your class.

This has a similar effect as the method level version, but now the traversal is just done once each time your class is instantiated and then held  in scope for the life of your object.

The result run under Flash Player 9.

  • Static prop lookup through class reference in class: 197ms

And with Flash Lite 2.1 under the Sony Ericsson W51S emulator.

  • Static prop lookup through class reference in class: 422ms

You’ll notice this result is slightly slower than the local method version. This is because each static access requires the class level reference variable to be pushed onto the stack. i.e. push easeType, push IN where as the method version just uses push IN once it has the class in scope.

As with most optimizations there are of course downsides. The primary one here being loss of static (as in compile time) type checking. By optimizing at class level your loss of type checking is more prevalent making debugging potentially more tricky, while at method level this is less of an issue. This is one reason I tend to optimize at the method level first, and then if need be at the class level, remembering to provide clear comments too.

I should make clear that on the web this optimization is not needed much of the time, but on the mobile it’s something which should be thought about throughout development.

You can grab the test code and flasm output here.

My next post will continue on this topic describing other considerations to be taken into account when dealing with statics.

  • Nov
  • 29th
  • 2008

One Year On

, , ,

Almost a full year has passed since I last posted so I figured it was as good a time as any to brush the dust away and write a summary of the past 12 months.

I had a great new years eve last year, probably the best I’ve had, at the Arches in Glasgow with my now former flat mate (he’s emigrated to Oz). Eric Prydz was playing and well, you can’t beat that place for a great atmosphere.

Around December I started hitting the gym 4-5 times a week with a colleague of mine. We were there at 6:30am most weekday morning. This carried on for around 7 months and we both made some great progress. In May/June my training partner moved down to London for work and It’s been somewhat down hill from there. I am getting back into it again now, but keeping an eye out for a new gym buddy as it makes it good deal easier to get out of bed!

Work has been going well with two promotions in a short space of time. I’m now a Principal Engineer, in charge of architecture and quality across the Flash teams.

In June I spent a month in Kuala Lumpur on site with the Flash team there providing training and support during an intense delivery window. The guys in the office really went out of their way to make me feel at home which made the stay that much more enjoyable. Working on the 51st floor of the Petronas Towers is something I won’t forget any time soon either.

In August I headed over to Vancouver to attend my cousin’s wedding. This was the first wedding I’d been to since I was about 6 but I can safely say it was a great one, with a wonderful setting, weather and people. It was fun catching up with my other cousin, aunt and uncle too, and meeting loads of family I never get the chance to see.

Since I returned from that holiday (actually the day I returned) I’ve found a really nice little apartment and moved in on my own. The move came about due to the emigration of my old flat mate to Australia. I contemplated moving in with another flatmate but the chances of getting on as well as I did with my old one were slim and I quite fancied  having my own space. So far I’m loving it!

Back at work, over the past month or so at work I’ve (re) designed and developed a lightweight component framework in Flash for mobile. Last year I carried out a similar task with some success, but deadlines and other business needs meant I was never given the chance to complete it and undertake some much needed optimizations. Looking back this was a shame as we’ve struggled in this area, but now with a little more weight behind me, I’ve had the chance to push this through and the benefits are becoming apparent.

I’m hunkering down for the next few weeks and then it’s off to Cairo with my mum to spend Christmas with my sister and her partner. It’s been a while since we all spent Christmas together so I’m really looking forward to it (and a little sun!).

Ah and one last thing. In February my laptop died, and I mean totally died. Of course it was just out of warranty so I was faced with spending £3-400 on repairs or moving to use a work laptop. I opted for the latter but this has meant I’ve not been able to get to some of my code, including the dependency injection (DI) framework I was working on (yes I should have backed up, and yes I do now use a remote repository to store my work :) ) Since then a number of AS3 DI frameworks have been released which offer similar features, but I still plan to complete and post my work when I get access to it again.

That about covers it. My aim is to be somewhat more regular with posts, and keep focus towards mobile UI development as that’s may main area of expertise. I reserve the right to deviate however.

  • Dec
  • 2nd
  • 2007

New SWX Backpack Service

, ,

I was lucky enough to catch Aral’s talk on SWX during this years Flash on the Beach conference in Brighton. Although already somewhat familiar with the project, his session inspired me to become active and develop a service which might be of use to some people.

I wanted to choose a service which could have some potential in the mashup and mobile space so after some thinking I decided upon the Backpack service from 37Signals.

What is Backpack?

The aim of Backpack is to help you keep your life organised. Whether it’s an event you’re planning or some thoughts you’re collating, this online application allows you to assemble, edit and share these in a simple and flexible manner.

On top of this, Backpack also includes a reminders system which is capable of dispatching an email and/or a sms to the account holder at a predefined point in the future.

There are far to many ways Backpack can be used for me to go into here but for some ideas take a look at these examples.

Getting Started

You can jump right in by heading over to the public gateway (hopefully part of Aral’s one soon). There you will find the Backpack service along with a mock account if you don’t have one yourself. You are free use this to help you become familiar with the api and result sets. A good place to start is the ‘getAllPages’ method which will return the page id’s of all pages within an account and with a page id in hand you can then query a page for items such as notes, emails and lists. To take a look at the contents of an entire account then try the ‘exportBackpack’ method.

If you would like to host your own SWX Backpack service you will first need to download and install the SWX PHP Gateway and then download the latest version of the Backpack service through the link at the bottom of this section. You will notice that the download contains an updated version of the BaseService class. I am hopeful this will be integrated into the trunk of SWX soon, but until then you will need to replace your copy in the ’swx/php/’ directory with this one. For those interested, this update adds a ‘_xmlCall’ method which uses SWXml to translate the xml result of an api call to object form. It adds SSL fall back support if cURL is not installed but OpenSSL is, and finally it allows you to add custom headers to a requests.

In order for this service to function correctly you will also need Flo’s SWXml service. This should be integrated into the SWX Gateway download at some point, but if it’s not present then you can download it from here. Simply place his service class alongside the Backpack class inside the ’swx/php/services/’ directory and you’re set!

Download SWX Backpack Service (0.7.2) (.zip).

A Look at The API

So what kind of things can you do with this new SWX Service?

  • Global Operations
    • Get All Pages
    • Get Pages With Tag
    • Search All Pages
    • Get Upcoming Reminders
    • Export Backpack (Exports your entire account)
  • Page Operations
    • Create
    • Update Title
    • Duplicate
    • Reorder Contents
    • Get All Lists
    • Get All Notes
    • Get All Emails
    • Share (with friends or the world)
    • Unshare
    • Email to Self
    • Tag
    • Destroy
  • List Operations
    • Create
    • Update Title
    • Get All List Items
    • Destroy
  • List Item Operations
    • Create
    • Update Label
    • Reposition (up, down, top, bottom)
    • Toggle Selected
    • Destroy
  • Note Operations
    • Create
    • Update Title and Body
    • Destroy
  • Email Operations
    • Destroy
    • [Every page has a unique email address which you can send emails to. This address can be found in the result of a ‘getPage’ request]
  • Reminder Operations
    • Create
    • Update Time and Body
    • Destroy

That’s all! If you do use this service in an application I would love to hear about it :)

  • Nov
  • 21st
  • 2007

Flash on the Beach 07 in Review

, , , ,

I’ve not updated for quite a number of weeks due to being stupidly busy, but now with a week off I thought it was about time I posted my review of FOTB 07. Better late than never!

Flash on the Beach was an excellent event. I’m so pleased that my employer recognised the benefits of sending myself a number of my colleagues down to Brighton. Here’s an overview of the sessions which stood out for me.

Monday

It was great to see Grant Skinner kick things off on Monday after the keynote. Although he didn’t include (or dropped) the topic of AVM2 garbage collection, overall I really enjoyed the pace and coverage of his session.

Mike Chambers did a good job introducing AIR. The talk was not very technical due to being geared towards entry level developers, but his perspective on the placement of AIR applications in the current RIA climate was insightful.

Niqui Merret’s session on accessibility was great. The pirate theme (Arrr) was fun and backed up with some very useful content. I may post more on this later as it generated a few interesting ideas.

Next up was Josh Davis. It’s safe to say he blew everyone away with his energy and passion and the pure quality of his work. What else can I say, you had to be there.

Tuesday

SWX! If you don’t know about it by now where have you been?! Seriously though, it’s a simple native data format for Flash remoting and if you work in the mobile space (shoot even if you don’t) it’s just too good to overlook.

Back to the SWX session, Aral had a pretty major issue with connectivity half way though his talk and this did cut out a good 15 minutes of live walkthroughs but even with this hurdle it was fun and informative.

Dave Yang’s Flash Lite session was one of the only disappointments. It felt like a calamity from start to finish and aside from the technical difficulties, and very late start, it just didn’t have any depth of content. I guess coming from a career in this sector my expectations may have been set too high. I do hope next year they have more emphasis on mobile platform development with some down and dirty technical sessions.

Robert Hodgin, wow. Simply inspirational work that made you wonder how such things can ever be created. I urge you if you haven’t already, to go and check out his work.

Wednesday

Carlo Blatz is a real funny guy. His talk on FDT3 was perhaps more a recovery session from the night before, but then again I think it was for most of the people in there :) It really didn’t matter though because the breadth of FDT3 features covered spoke for themselves. I also picked up quite a few tips which I have already integrated into my development workflow. If you haven’t already, go give FDT3 a try, oh and make sure to learn the shortcuts.

Jared Tarbell, wow for a third day in a row. His walkthough of computational art was quite inspiring. This was perhaps a more technical talk than the previous 4pm sessions, but it didn’t fail to blow everyone away once again.

A big thanks to John Davey and team for hosting a great event and I hope to be back again next year for more of the same.

  • Oct
  • 22nd
  • 2007

Flash on the Beach 07

, , , ,

In less than two weeks I’ll be heading down to Brighton to attend my first all out Flash conference… and I can’t wait!

Flash on the Beach 07

From all accounts last years Flash on the Beach was a total success, and after looking at this years lineup I’m expecting more of the same.

So tonight I finally got the time to sit down and run through the sessions I’d like to attend. Believe me, this was no easy task! Here’s my final (for now) schedule.

Monday 5th

09:00 Keynote

10:15 Grant Skinner - 50 Reasons AS3 Kicks Ass, (I’d also love to see the Localising Flash Content and Applications presentation by Dave Williams)

11:30 Mike Chamber - Understanding Adobe AIR

13:30 Lee Brimlow - Adobe Air for Interactive Designers

14:45 Niqui Merret - The Pirates of Accessibility

20:00 Brendan Dawes - If it ain’t broke - break it!

Tuesday 6th

09:00 Ted Patrick - Flex and ActionScript 3.0 Worst Practices

10:15 Craig Swann - Perceptive Interactions & Alternative Interfaces

11:30 Aral Balkan - Lets Talk about SWX, baby!

13:30 Dave Yang - Mobile Flash Development (difficult choice as i also want to see Carlos Ulla’s session on Papervision)

14:45 Stephen Downs - Flashing Flex

16:00 Joshua Davis - Dynamic Abstraction

20:00 Erik Natzke - Beyond the Knowledge: The Art of Playing

Wednesday 7th

09:00 Chris Allen - Building Red5 Applications (Unfortunately missing the Adobe Town Hall Meeting, but I’ve been wanting to learn more about red5 for a long time!)

10:15 Joey Lott - Stylizing Flex Applications

11:30 Carlo Blatz - Optimizing Workflows with Eclipse and FDT 3.0

13:30 Branden Hall - The Nooks and Crannies of ActionScript 3.0

14:45 Mike Jones - Flex Application Development - Done in 60 Minutes

16:00 Jared Tarbell - Algorithms to Fill Space

See you all there!

  • Oct
  • 3rd
  • 2007

Custom Metadata in AS3.0 Class Definition

, ,

For the past month or so I have been spending the odd evening porting a well known Java based dependency injection framework to ActionScript 3.0. Integral to this port is the ability to bind framework specific metadata to class members and for the runtime interpreting of this meta.

Thankfully the AS3.0 compiler provides a compiler option to retain meta bound to class members. Namely:

keep-as3-metadata=class_name [...]

This option will retain any meta bound to class members for runtime examination through the class xml definition.

Now for the bugs.

The first annoying but not so serious one I have discovered is the lack of support for binding metadata to a class constructor. All other members will retain their meta, but a constructor seems not carry its meta into the class definition. To get around this I bind constructor specific meta at the class level.

The second is a critical bug which stopped me dead in my tracks. It appears that this metadata is only carried into the class definition when building in debug mode. In a production built swf, the compiler strips this data out so you are unable to examine it at runtime.

For my current project I intend to support both an internal and external DSL, so this issue is not so much a show stopper than a redundantly supported feature.

I should state that I am testing using the Flex 2 SDK, I will do some further tests with the Flex 3 beta SDK to see if either of these issues have been fixed.

[UPDATE]
OK so I’ve done some quick testing with the Flex 3 SDK and it’s looking positive. The major issue of carrying meta into production swfs has been fixed which is great news.

On the issue of binding meta to a class constructor it appears that this has not been solved. Of course this may be an underlying Flash Player bug but if not, then fingers crossed the final v3 SDK will rectify this.

Status

Calendar

  • December 2008
    M T W T F S S
    « Nov    
    1234567
    891011121314
    15161718192021
    22232425262728
    293031  

Links

Recent Photos

Tags