Ted Patrick > { Events & Community } > Adobe Systems


It turns out primitive values have a hidden performance problem. At runtime, primitive values are changed into Objects when they are accessed with the "." Operator.&

It seems that when you use the "." Operator on a primitive value it upgrades the primitive to a hidden object of equivalent type. For example:

a = "Hello World"
a.split() //primitive upgraded to new String("Hello World") before "split" is called.

a = true
a.valueOf() //primitive upgraded to new Boolean( true ) before "valueOf" is called.

a = 23
a.valueOf() //primitive upgraded to new Number( 23 ) before "valueOf" is called.

The problem is that for each access to a primitive value (use of "." Operator), a hidden object is created and destroyed. If you use the object originally, the hidden object is never created.

From what I gather primitives do not provide access to the Class and thus must be turned into an Object to allow for methods or properties usage. The results occur very fast as they are within the player code, but they do impact both AS performance and memory consumption/garbage collection.

Here is a little proof. Run the test twice changing the value of the "a" variable from a primitive to an object.

//PRIMITIVE STRING
a = "Hello World"

//OBJECT STRING
//a = new String("Hello World")

i=10000
while(i--){

//if a is a primitive, it will be upgraded to an Object
//if a is an object, it will directly execute the method
a.split(" ")

}
trace( getTimer() )


In my tests:

String Primitive: 310
String Object: 221 //faster AS execution using Object

**Access to String.length is equivalent in speed in object or primitive**

Number Primitive: 140
String Object: 62 //faster AS execution using Object

Number Boolean: 135
String Object: 71 //faster AS execution using Object


The hidden problem is memory consumption and garbage collection. In the Object case, there is only one object created, where as, in the primitive case there are 10,000 objects created and destroyed and ready for garbage collection. Yes, your heard that correctly, there are 10,000 extra useless objects in player memory to be garbage collected because a primitive value was used. This forces the player to do allot more work than it needs to and forces many more objects into memory to be disposed.

Long story short, use the Object version of primitive values in your application and not the primitives themselves especially for method intensive variables. If you use methods or properties on primitive values, the player is forced to create and destroy an object with each access.

I certainly would have thought that the primitives would be faster. Is that weird or what?

Cheers,

Ted ;)

11 Responses to “ Primitive Performance - The hidden object on "." Operator use ”

  1. # Anonymous JesterXL

    Curious if that applies to Array, since I love doing:

    a = []

    vs.

    a = new Array()  

  2. # Anonymous caseyc

    Array seems to work as expected:

    a = "String";
    trace(a instanceof String); // false

    a = [];
    trace(a instanceof Array); // true  

  3. # Anonymous Intoxo Pox

    Swell tip. Who'd a thunk it.
    Now to go and run some test.  

  4. # Anonymous Andre Michelle

    Cannot agree. Only Strings are faster in this enviroment. For Booleans I've got the same values and for Numbers, it is much slower.

    This is found earlier by Holger Kohnen:
    http://www.flashfanatiker.de/blog/archives/000026.html  

  5. # Blogger Ted Patrick

    Andre,

    Here is the code for testing Boolean and Number access. The only change is calling the "valueOf" method vs. "split" method.

    //PRIMITIVE STRING
    a = 23

    //OBJECT STRING
    //a = new Number( 23 )

    i=10000
    while(i--){

    //if a is a primitive, it will be upgraded to an Object
    //if a is an object, it will directly execute the method
    a.valueOf()

    }
    trace( getTimer() )

    Cheers,
    ted ;)  

  6. # Anonymous Andre Michelle

    yes, it's faster when you are calling methods on primitive objects.
    But Numbers and Boolean are mostly needed on calculations or logical expressions. If you need to compute a*b, then it's much slower to declare them as Objects. Didn't find it in your accomplishment.  

  7. # Blogger Ted Patrick

    Andre,

    The test certainly isn't complete. I think it depends on what you are doing. Method access for primitives seems to be the real problem I am talking about.

    Expressions and math operations need additional testing. It does look as though Boolean and Number operations on primitives are indeed faster.

    So the cases are varied. String addition seems faster with primitives but Method access is faster with Objects.

    Strange results.

    Ted ;)  

  8. # Anonymous Andre Michelle

    http://blog.andre-michelle.com/2005/methods-on-primitives-performance/

    my 10 cents :)
    we have to reseach furthermore.  

  9. # Blogger Ted Patrick

    I am so confused and this is my blog!

    More testing needed indeed!

    ted :)  

  10. # Anonymous bokel

    This fact is long known :)

    It may pay out, if you have a lwhole ot of method calls on one particular string. A situation, i never met until now.

    Moreover it is dangerous to use the Boolean objects, as you can see here:

    var b = new Boolean(false);
    if( b) trace( "hey"); //output hey

    Cheers,
    Ralf  

  11. # Blogger Beau Scott

    FYI, I cannot reproduce Bokel's example in Flex 2.01 hotfix 3 or Flex 3 beta 3, it works as expected. I wanted to see if strong typing the variables had any impact, and it does not.

    var b1 = new Boolean(false);
    if(b1) trace("Failed test 1"); // Does not output

    var b2:Boolean = new Boolean(false);
    if(b2) trace("Failed test 2"); // Does not output  

Post a Comment



© 2008 Ted On Flash