Categories Displayed in Flash

Archive for the 'switch' Category

Performance: Strict equality === versus compare by value ==

One of the cool features little used in actionscript is the strict equality operator '===' what this does is evaluate if two pointers endup at the same address in memory, rather than the contents of that address. This is similar to the performance increase of looking at the mailing address on two envelopes rather than actually going to the address, knocking on the door to see who lives there. But this only works for pass by reference (Object) vrs pass value types (e.g. int, uint, boolean) and during comparions those that don't compare by value (e.g. Number, String).

Coding wise, I also like switch statements, they are clean visually and semantically, and AS3 has the neat feature to allow any type to act as a switch value, other languages like Java/.Net restrict case statements to primitives numbers, or strings.

I created a class to test raw performance of different types/approaches used in switch statements, primarily to determine whether strings (as passed by event e.g. Event.type), numbers or signals (as done by cogs) is faster approach, and if switch statements could use strict equality or by value.
Full Fledged Classes used as the case statement and switch are the fastest at close to 1/3 the time. This is great as it offers author time compile checking, strong typing at runtime. Lookups are likely by identity (===) instead of by value (==) as in data types even when those are marked static and constant, which means performance is about twice that of using a value comparison, in addition, since they are fullfledged objects they can contain all sorts of things (e.g. toString, operations).
Downside is that no numerical id is attached by number by default, so it's harder to index and later lookup these values when they exist in a random collection of some sort, but since it's a full fledged object, adding an id variable is easy.

In the class containing the switch, e.g.

//277ms for 100K
switch(stringVal){

case JanuaryStaticConst:
case "January":
break;
}

//177ms for 100K
switch(intVal){

case 22:
break;
}

//166 ms for 100K iterations

switch(objRef){

case Class.StaticVal:
break;
}

//98 ms for 100K iterations

static const var StaticVal = Class.StaticVal;
switch(objRef){

case StaticVal:
break;
}

Flash's compiler doesn't replace Class.StaticVal, with StaticVal so there is a lookup overhead. So it's recommended that you capture a reference in a static const (see recommendations at end)
For primitive data types (String, number, int, etc), strings are about 70% slower than any numbers, potentially the length of
the string may also impact the performance (not tested). Note that even making the string a static const string offered
no performance increase (though probably a significant memory performance increase) because your using value comparison (==) in the switch statement
versus identity (===).

The fastest numerical type, was an typically an int though this wasn't really repeatable, or significant. But might
make sense to use if your using it as bitflag.

Test Results for 100K iterations:
SwitchNumber 177
switchInt 176
switchUInt 170
switchString 277
switchStringConst 275
switchIntConst 175
switchCogSignal 166 <-- lookup of CogSignal.SIGNAL
switchCogSignalB 97 <-- 'cached' CogSignal.SIGNAL pointer (set via static constructor)
switchSwitchSignal 98 <- declaring it internally
Recommendations:
1) use a custom class, static const on the class
e.g.

//cache the value during class/static initialization
public static const C_0:SwitchSignal = SwitchSignal.C_0;

and later

public function switchSwitchSignal(sig:SwitchSignal):void{
switch(sig){
case C_0: //SwitchSignal.C_0, but no lookup overhead.

2) for raw data types use int, instead of (uint, Number).