views:

141

answers:

4

I'm (still) trying to solve an issue in my 2D Flash game where my framerate is dropping to unacceptable lows. I have a class with the following member variable and method:

protected var value:*;
public function getValue () :* {
    return this.value;
}

Right now, that method is being called seemingly a few hundred times per frame and 2.23% of my application time is spent in that method.

Do you think that I'll notice a significance performance increase by making value a typed variable? Making that variable typed will make code all over the application break so I'd like to be more sure that it will actually help.

Also, here's the top few records of the Performance Profile for my application, sorted by Self Time, which led me to suspect this getValue() method in the first place:

Method                             Calls    Self Time (ms)
------                             -----    --------------
[pre-render]                       0        2137 (19.68%)
[reap]                             0        727 (6.7%)
[enterFrameEvent]                  0        464 (4.27%)
[mouseEvent]                       0        352 (3.24%)
[mark]                             0        327 (3.01%)
State.getValue                     792356   242 (2.23%)
[verify]                           0        209 (1.93%)
[render]                           0        159 (1.46%)
CollisionManager.detectCollisions  584      156 (1.44%)
Entity.updateAllStates             30227    154 (1.42%)
Entity.getStateValue               392412   143 (1.32%)
GSVector.set y                     156244   141 (1.3%)
State.update                       659738   123 (1.13%)
A: 

Given that you are already using the profile, why don't you just try it and see?

Slow framerates in a Flash games are not normally code related. Try turning on "redraw regions" and see what is being redrawn on each frame - you're probably redrawing too much.

On topic, there's no reason for you to be using *, unless the state can also be a Namespace. Everything else inherits from Object. Do your states not have a common ancestor or interface?

Edit: Actually, now that I think about it, you are calling getValue a LOT. Assuming you are calling CollisionManager.detectCollisions once per frame, you are calling getValue 1356 times per frame.

If you are calling this methods several times within one methods, try getting the value once and storing it in a local (scoped to the function) variable. You could even pass the value into other methods, to reducing the calling count of this function.

Richard Szalay
It will take many hours to make that change so I'm polling SO to see what you all think :) Thanks for the tip about redrawing!
Kai
A: 

If you can run it under the debugger, put your per-frame code in a flat-out loop, and try this.

Mike Dunlavey
A: 

First, you should be using typed variables. It improves code readability, ensures type safety and can improve performance. The only situation I have found a need to use :* is when I am writing a collection class and want it to be reusable for a variety of different types (Adobe bring on generics!).

Calling a property or function does incur overheads, while it is not great OOP if you made the variable public and accessed it directly it would improve performance.

I also suspect that something else may be accounting for your frame rate drops. Since it appears you are doing some sort of collision detection you should have a look into quadtrees if you are not doing so. Quad trees split up regions so that you can reduce the amount of checking for collisions.

Allan
You should be using Object in the collection scenario. As I mention in my answer, * only adds things like namespaces.
Richard Szalay
The Array and Dictionary class in AS3 both seem to have the return type of * so I am keeping it consistent with their collection classes. You can test this as Objects can not be undefined yet Dictionary and Array can return undefined so they must return *
Allan
+1  A: 

In a word, yes. Strong typing is one of the principle reasons why AS3 is faster than AS2 (because in AS2 all variables are untyped, and every time you reference an untyped variable Flash has to internally check what type it is).

Normally for a question like this I'd hem and haw about the pitfalls of performance tuning, about how architectural changes are usually more effective than code-level tuning, and how most content is bottlenecked by rendering rather than code execution... but in this case, using typed variables is something you should be doing anyway, as it makes your code more robust, more readable, easier to maintain, and less prone to bugs.

There's really no good reason for using untyped variables in AS3. Take the time to make this change, and it will pay off in the long run even if you don't see a performance increase (though I think you will).

fenomas