Primitive Performance - The hidden object on "." Operator use
DIGG IT!
11
Comments
Published
Thursday, June 09, 2005
at
8:05 AM
.
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 ;)

Curious if that applies to Array, since I love doing:
a = []
vs.
a = new Array()
Array seems to work as expected:
a = "String";
trace(a instanceof String); // false
a = [];
trace(a instanceof Array); // true
Swell tip. Who'd a thunk it.
Now to go and run some test.
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
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 ;)
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.
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 ;)
http://blog.andre-michelle.com/2005/methods-on-primitives-performance/
my 10 cents :)
we have to reseach furthermore.
I am so confused and this is my blog!
More testing needed indeed!
ted :)
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
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