How slow is static access in as3/avm2 (exactly)

A reader’s comment to my previous post on Singletons asked for some evidence that static access in as3 was indeed ’10 times’ slower. I remembered having read the 10 times thing somewhere, but couldn’t find anything by quick googling. Uneasy, I decided to put up a quick benchmark. I went through more than one surprise. The code can be found here.

Four tests are being performed at 1m iterations:

1] The first test compares access times to a propety of the calling object and a static property of the class definition. Both are accessed without ‘.’ opertators: they are simply referenced by their names.

2] The second test does the same, but for propeties of a referenced object. The object’s property is accessed with a typedReference.propertyName syntax, and the static property through a ClassName.propertyName syntax.

3] The third test compares call times for a method of the calling object and a static method of the class definition. The access syntax is the same as in the first test.

4] The last, fourth test compares method call times on a referenced object. This is done like in the second test.

Without thinking too much about it, I compiled in debug mode, and ran the swf in fp10 debug. Output was as follows (imagine my surprise):

Getting & setting a property of this object :          104 millisec
Getting & setting a static property of this class :    109 millisec
Static access is slower by :                           5%

Getting & setting a property of another object :       106 millisec
Getting & setting a static property of another class : 178 millisec
Static access is slower by :                           68%

Calling a method of this object :                      317 millisec
Calling a static method of this class :                318 millisec
Static access is slower by :                           0%

Calling a method of another object :                   311 millisec
Calling a static method of another class :             397 millisec
Static access is slower by :                           28%

Thus no slowdown at all! I was already writing my apology to the reader when I realized my mistake. I recompiled the benchmark in release mode; while still running in fp10 debug, numbers changed dramatically:

Getting & setting a property of this object :          7 millisec
Getting & setting a static property of this class :    10 millisec
Static access is slower by :                           43%

Getting & setting a property of another object :       8 millisec
Getting & setting a static property of another class : 94 millisec
Static access is slower by :                           1075%

Calling a method of this object :                      90 millisec
Calling a static method of this class :                93 millisec
Static access is slower by :                           3%

Calling a method of another object :                   92 millisec
Calling a static method of another class :             176 millisec
Static access is slower by :                           91%

Finally, I opened the swf with fp10 release. Things sped up even more, and the static access overhead increased its significance in % terms. Funnily, there was one exception to the reduced timinings, in fact getting and setting a static property of another class proved to be slower in the release player than in the debug player. I would blame this on my selection of players, even though I am pretty confident I got the debug and release players in the same zip from the Adobe website.

Getting & setting a property of this object :          7 millisec
Getting & setting a static property of this class :    10 millisec
Static access is slower by :                           43%

Getting & setting a property of another object :       6 millisec
Getting & setting a static property of another class : 133 millisec
Static access is slower by :                           2117%

Calling a method of this object :                      10 millisec
Calling a static method of this class :                13 millisec
Static access is slower by :                           30%

Calling a method of another object :                   12 millisec
Calling a static method of another class :             142 millisec
Static access is slower by :                           1083%

The moral is twofold. On the one hand, accessing the static stuff of a class from within the scope of the class itself is not too expensive (which also means that Borg designs in as3 are not all that much of a bad idea performance-wise [I was wrong]), but accessing the static stuff on other classes through their Class objects is indeed very slow and should be, clearly, avoided when performance is at stake. The other is to remember the ‘Benchmarking gotchas’: or to always compile benchmarks in release mode and run them in the release player: debug mode/player can produce very distorted timings.

Bookmark and Share

11 Responses to “How slow is static access in as3/avm2 (exactly)”


  • An excellent article! I personally haven’t come across any tests determining the speed of static access and this demonstrates the subject very well – thanks for spending time on this and sharing your findings! :)

  • My pleasure, you raised a good point in the first place.

  • Now I want to see how speed of access to package-level functions compares.

  • Ha, true. I never use them, but I suppose it could be interesting.

  • While there are reasons to understand the ‘static’ overhead, I wonder what happens when you make use of ‘static const’, as this is used a lot in as3 classes to mimic enums.

    • Nothing – the compiler leaves static constants as ‘variables’ on the class – and the code retrieves the values at runtime.
      It would have been so easy to make the compiler inline what are references to compile-time available constant literals in the code (selectively maybe, but at least what’s short strings, integers, booleans and numbers). I am truly amazed by how a team of developers can undermine their own work – in this and many other cases the compiler openly offends the performance potential of the virtual machine.

  • Is there a good workaround for keeping static constants fast? I suppose each class could make a copy of the static variables inside their own class, that way access is fast. But that is messy. What is a good way?

  • If you are looking for a way to make static access quicker, the answer is no; but listen, depending on what you are doing with static constants, you most probably don’t have to bother. (Event handling and type enums is a good example, you really don’t care about efficiency there.)

    But when there is a lot of static stuff going on, I usually resort to Borg designs – I wrap the static functionality in a class with its access points on the instances, but where all data is shared internally as statics. Then I can just instantiate this class and keep a reference to its instances here and there where I need it and that way can access the same functionality in a much more flexible way. If you add in some abstraction, you might end up with a very sound code architecture actually.

    My tweening engine works a bit like this if I remember correctly.

  • What about creating an event listener on a static method? Will that be slower or the same as an instance method since the handler reference is stored already in the listener? If I save out MAth.sin to public var sin:Function, i assume that would be much faster, albeit you use an additional pointer with increased memory.

    One of the thing about constants and static functions is that they can be inlined with a proper language like Haxe and such.

    I still sometimes resort to static access within a class internally ( more for internal static states, pooling, global timer to be started, etc.) even though this could be factored out to a separate “running” context class (saving out extra pointers from the static variables/constants within the class) which could make things a bit faster, albeit the latter would be much harder to set up.

  • What about creating an event listener on a static method? Will that be slower or the same as an instance method since the handler reference is stored already in the listener? If I save out MAth.sin to public var sin:Function, i assume that would be much faster, albeit you use an additional pointer with increased memory.

    One of the thing about constants and static functions is that they can be inlined with a proper language like Haxe and such.

    I still sometimes resort to static access within a class internally ( more for internal static states, pooling, global timer to be started, etc.) even though this could be factored out to a separate “running” context class (saving out extra pointers from the static variables/constants) which could make things a bit faster, albeit the latter would be much harder to set up.

  • If static consts are expanded and inlined, then execution may be faster but code size would be larger. So compiler developers went through the performance vs size trade off and settled for smaller size i think…

Leave a Reply