While writing that animated sine-wave thingy at the top of my web site, I ran into a problem -- my frame rate was terrible. I was getting maybe 3 or 4 frames a second. My browser was bogging down, my computer was bogging down. I had to either speed it up, or I had to dump it.
As it has many trig calculations in each frame, I thought that Math.sin() was to blame. I was getting ready to write a table-lookup algorithm to replace Math.sin, when the little angel on my shoulder told me to quit guessing and be more scientific about it. So I wrote a test program instead. I found that Math.sin was extremely fast and certainly not the cause of my problem.
I've been curious about the speed hit due to using class instances rather than generic objects. Way, way back, when I learned C++, the first class I wrote was Point. It was great. Because it used inline functions, it had virtually no performance hit over a raw data structure. And it made my code much cleaner. When I moved to C#, I found that it already has a Point class, which was also great. It was only natural that I write a Point class when I moved to ActionScript.
But I've noticed that not everyone uses a Point class. In code listings, I see generic objects with an x and y property used instead, or I see old-fashioned, separate x and y variables. I had to find out whether my beloved Point class was killing my sine-wave animation.
The code listing for my tests is below in the "Appendix" (it's boring to read, so I moved it out of the way). I put the test flash movie down there also so you can check the numbers on your computer.
Anyway, here's the results:
New vs. Reuse
Resusing a point in your loop rather than creating a new one every time is more than twice as fast.
// Create a new point on each iteration var p:Point = new Point(1.2, 3.4); // 34 msec / 1000
vs.
// Recycle the point. Use a function to set the values. p.set(1.2,13.4); // 15 msec / 1000
Not surprising. Creating a new instance involves allocating memory, which is nearly always slow.
Setting Data Members: Via Function vs. Direct
Setting the data members directly is 3x as fast as setting them through a function.
// Recycle the point. Use a function to set the values. p.set(1.2,13.4); // 15 msec / 1000
vs.
// Recycle the point and set the values directly. p.x = 1.2; p.y = 3.4; // 4 msec / 1000
Again, not surprising. Calling function is slower than not calling a function.
The data members need to be public to do this. Operating on data members this way is NOT the object-oriented way. We are not encapsulating the internal operation of our class.
It's a tradeoff. Based on the needs of your flash movie, you'll have to decide what's more important.
Class Instances vs. Object Instances vs. Object Literals
Creating a new Object is about twice as fast as creating a class instance. Surprisingly, the object literal syntax is significantly faster than the new Object syntax.
// Create a new point on each iteration var p:Point = new Point(1.2, 3.4); // 34 msec / 1000
vs.
// Use an Object instead of a Point instance. // 17 msec var p:Object = new Object(); p.x = 1.2; p.y = 3.4;
vs.
// Create a new object literal
var p:Object = { x: 1.2, y: 3.4 }; // 13 msec.
Why is "new Object" faster than "new Point"? All classes are derived from Object. Part of the process of creating a class instance is creating an Object. So, of course, creating an Object is faster than creating an Object combined with something else.
Why object literals are faster than new object, I don't know. Maybe it's because it's one line of code instead of three. But for now on, I'm using the literal syntax.
Object vs. Class Instance Data Members
Directly setting the data members of a class and an Object are equally fast.
// Set the public data members directly. var p:Point = new Point(); p.x = 1.2; p.y = 3.4; // 4 msec / 1000
vs.
// Set the public data members directly. var p:Object = new Object(); p.x = 1.2; p.y = 3.4; // 4 msec / 1000
Affect on my Coding Style
In general, I prefer to use Classes rather than generic Objects. With classes, you get:
- type checking
- code hinting (if you have a decent editor)
- encapsultation
But there is a balance point. You don't create a class to encapsulate a single number, for example. Where do you draw the line? What one coder might call an elegant design, another might call "over-engineered."
Until now, my ActionScript coding style has been basically the same as my C++ coding style. But ActionScript is a different animal. My balance point has shifted. The performance implications for certain constructs are too big to ignore.
I'll tend to use class definitions for large-memory or low-instance-count objects that don't get created in onEnterFrame or onMouseMove.
I've dumped my Point class -- now they're generic objects. Generally, I use points in performance tight situations where overhead must be minimized. Switching to generic-object points is the main reason my animated sine-wave actually works now.
ActionScript Performance Links:
www.oddhammer.com/actionscriptperformance/
Appendix
You can run the tests on your computer. This was built for Flash 7.

Here's the code being tested. Notice that each function has a line in the above Flash movie (assuming you ran the test).
class com.connectedpixel.apps.perftest.ClassVsObjectCompare {
static public function newPoint():Void {
for (var i:Number = 0 ; i < 1000 ; i++){
var p:Point = new Point(23.4,12.3);
}
}
static public function recyclePoint():Void {
var p:Point = new Point();
for (var i:Number = 0 ; i < 1000 ; i++){
p.set(23.4,56.7);
}
}
static public function setDataMembersDirectly():Void {
var p:Point = new Point();
for (var i:Number = 0 ; i < 1000 ; i++){
p.x = 23.4; p.y = 56.7;
}
}
static public function newObjectAndProps():Void {
for (var i:Number = 0 ; i < 1000 ; i++){
var p:Object = new Object();
p.x = 23.4; p.y = 56.7;
}
}
static public function newObjectLiteral():Void {
for (var i:Number = 0 ; i < 1000 ; i++){
var p:Object = { x:23.4, y:56.7 };
}
}
static public function recycleObject():Void {
var p:Object = new Object();
for (var i:Number = 0 ; i < 1000 ; i++){
p.x = 23.4; p.y = 56.7;
}
}
}
Here's the Point class that's used in the above code.
class com.connectedpixel.apps.perftest.Point {
public var x:Number;
public var y:Number;
public function Point(x0:Number, y0:Number)
{
x = x0; y = y0;
}
public function set(x1:Number, y1:Number):Void
{
x = x1; y = y1;
}
public function getX():Number { return x; }
static public function staticGetX(p:Point):Number
{
return p.x;
}
}
