Namespaces As Function Pointers
One lovely trick C/C++ programmers can use is to replace conditional logic (eg. if statements) with function pointers if the result of the conditional logic is a loop invariant. Function pointers do exist in AS3 in the form of the Function class, but they are a dynamic class whose usage is very slow. AS3 also supports Namespaces, which can be used as a function pointer substitute. Are they any faster than directly using Functions? Read on for a quick test.
Here is a simple test of accessing a different variable, which could easily be a function, a lot of times in three ways: directly, via an explicit namespace references, and via a Namespace variable:
package { import flash.display.*; import flash.text.*; import flash.utils.*; public class NamespacesTest extends Sprite { namespace monkey; namespace taco; monkey var val:String = "monkey"; taco var val:String = "taco"; private var val2:String = "val2"; private var __logger:TextField = new TextField(); public function NamespacesTest() { __logger.autoSize = TextFieldAutoSize.LEFT; addChild(__logger); var i:int; var s:String; const NUM_ITERATIONS:int = 50000000; // Explicit namespace usage var before:int = getTimer(); for (i = 0; i < NUM_ITERATIONS; ++i) { s = taco::val; } log("Explicit namespace usage time: " + (getTimer()-before)); // Namespace variable usage var ns:Namespace = monkey; before = getTimer(); for (i = 0; i < NUM_ITERATIONS; ++i) { s = ns::val; } log("Namespace variable time: " + (getTimer()-before)); // No namespace usage before = getTimer(); for (i = 0; i < NUM_ITERATIONS; ++i) { s = val2; } log("No namespace time: " + (getTimer()-before)); } private function log(msg:*): void { __logger.appendText(msg + "\n"); } } }
The results I get on a 3.0Ghz Intel Core 2 Duo with 2GB of RAM on Windows XP SP3 are:
Explicit namespace usage time: 113 Namespace variable time: 4745 No namespace time: 112
The results I get on a 2.2Ghz Intel Core 2 Duo with 2GB of RAM on Mac OS X 10.6 (Snow Leopard) are:
Explicit namespace usage time: 154 Namespace variable time: 7559 No namespace time: 154
These results are consistent across the two test computers and simply show a scale corresponding with the CPU speed. They indicate that direct usage and explicit namespace usage are equivalently fast, but a Namespace variable is 288% slower, just like you would expect from a dynamic class like Namespace or Function. The up side here is that you won’t cause any slowdown by using namespaces, just so long as you don’t use them as a variable to implement a function pointer-style speedup strategy. The reason seems clear: the namespace is simply creating a different name for two otherwise-identically-named functions and that difference can be unambiguously resolved at compile time. This is one time that MXMLC is doing that optimization work well.
In conclusion, do not look to Namespace variables for a function pointer-style speedup. You will slow your code down immensely in the process.
#1 by Simon Richardson on February 5th, 2011 ·
Interestingly enough, I was thinking about using an external class to hold the name space and I found something interesting. If you use an explicit usage i.e. external_namespace I get an even worse time than a Namespace variable, by about 10% – so nearly 300% worse!
Assuming you have a namespace set up called extern_namespace.as which has the following code:
Then testing it without the use reveals 8256ms on my 10.1 release player :-s
With the “use” it’s the same as an Explicit namespace you tested above (see bellow). Note: you can’t test it with “use” and “explicit use” (i.e. extern_namespace::val) in the same test as “use” as it will be used by default causing the “explicit use” to be the same speed as “use” on it’s own (hope that makes sense)
#2 by jackson on February 5th, 2011 ·
I wonder what kind of results you’d get on Flash Player 10.0. My followup test with Flash Player 10.1 showed a 25% performance drop from the results in this article, so perhaps you’re just seeing that drop in your version. One can hope, at least. :)
#3 by Simon Richardson on February 5th, 2011 ·
Amazingly in the 10.45.2 release player namespaces on functions are quicker than 10.1, why is there a regression?
10.1.85.3
Use namespace usage time: 327
No namespace time: 269
10.45.2
Use namespace usage time: 222
No namespace time: 244
#4 by Simon Richardson on February 5th, 2011 ·
I didn’t even notice that there is a slow down in 10.1 just calling functions (private namespace).
#5 by Simon Richardson on February 5th, 2011 ·
Going to test on the Flash Player 10.0 now (just downloading it) – interestingly though external namespaces for functions are about 2.1% slower than using no namespace over 50000000 iterations, which is slightly worse than variables it seems (not by much though)