My favorites | Sign in
Logo
                
Search
for
Updated Oct 27, 2009 by ricardo.cabello
Labels: Featured, Phase-Deploy
stats  
FPS, MS and MEM. All in one.

This class provides a simple info box that will help you monitor your code performance.

  • FPS Frames per second, how many frames were rendered in 1 second, the bigger the better.
  • MS Milliseconds needed to render a frame, the lower the better.
  • MEM Memory your code is using, if it increases per frame is VERY wrong.
  • MAX Maximum memory the application reached.

Screenshot

How to use

Actionscript 3

addChild( new Stats() );

Javascript

element.appendChild( Stats.init(60) );

Controls

Download

Change Log


Comment by jonathandc, Aug 12, 2008

Very nice class indeed, thx !

Comment by kszyniu, Aug 13, 2008

what means "MS" parameter ?

Comment by info@mrdoob.com, Aug 13, 2008

Milliseconds since the last frame. I have included the definitions on the intro. Thanks :)

Comment by makc.the.great, Sep 06, 2008

perfect! just what I need for my new demo.

Comment by miquel7, Sep 30, 2008

Congrats mate :)

Comment by idyllhands, Dec 04, 2008

Thanks for the useful utility!!

Comment by info@mrdoob.com, Dec 14, 2008

Thanks for the ping. I've added the link to the Download part of the wiki. I've also updated the class to 1.4 :)

Comment by tuomas.arokanto, Jan 14, 2009

It might be worth noting, that adding this will slightly increase your program's memory consumption over time. It's simply because it has constantly running event listeners.

I just spent some time wondering what was eating away memory in my program and noticed that it was this one. The increase is very small though.

Great app!

Comment by info@mrdoob.com, Jan 15, 2009

Are you sure? I re-checked the code, I don't see any reason why it should increase memory consumption per frame... maybe the vars inside the loop?

Comment by huihuicn.xu, Feb 05, 2009

you code have a bug if remove this but listeners is still run, you must remove all listeners. my fix this code this.addEventListener(Event.REMOVED_FROM_STAGE, onRemovedToStage); private function onRemovedToStage(event:Event):void

{
this.removeEventListener(MouseEvent?.CLICK, onClick); this.removeEventListener(MouseEvent?.MOUSE_OVER, onMouseOver); this.removeEventListener(MouseEvent?.MOUSE_OUT, onMouseOut); this.removeEventListener(Event.ENTER_FRAME, update);
}

Comment by tuomas.arokanto, Feb 05, 2009

Mr Doob: I use FlashDevelop? so I just select a main class to start compiling from. If I make my Main class look like this:

package {

import flash.display.Sprite; import flash.events.Event; import net.hires.debug.Stats;

public class Main extends Sprite {

public function Main():void {
if (stage) init(); else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init); addChild( new Stats() );
}
}
}

Then if I wait a while, the memory consumption will increase slightly after a while. It probably frees the memory once the garbage collector runs (I didn't wait it out), because that's just how Flash Player works. I just mentioned it so that no one else needs wonder why it behaves that way.

Comment by info@mrdoob.com, Feb 06, 2009

@huihuicn.xu: the component was never designed in that way, like usually you have it or you don't have it. But I think you're right. I'll introduce a destroy() method for cleaning that up

@tuomas.arokanto: Yeah, flash player will start using some memory, and then at some unknown point goes down to, more or less, the starting memory amount.

Comment by info@mrdoob.com, Feb 21, 2009

So I was today profiling this website I'm working on, trying to find a memory leak and the I though it would be cool to have a MAX MEM value on the Stats. So I went ahead and added it.

The interesting thing was that I actually found a memory leak on the Stats itself, very tiny, but easier to spot with 2000 instances of it. To be honest I don't know the reason, it looks like a flash player leak with textfields. But I'm not sure.

As I was working on it I changed the text system and is now XML+CSS based. Performance and filesize is the same, but luckily, now the leak is gone.

All in all, it seemed to me that the versioning had to go to 2.0 as it has been more than a little feature or a little bugfix.

Right now the flash version on rollover is not there, I haven't found it really useful, let me know if you did.

Hopefully it keeps doing the job for what it's for.

Comment by thomas.brault, Mar 29, 2009

For my projects, I added two buttons :

§ one wich allow drag the stats anywhere on the window (usefull when you have something back the stats) § another wich call manualy garbage collector with this : try {

new LocalConnection?().connect('foo'); new LocalConnection?().connect('foo');
} catch (e:) {}

it could be idea for the next version !

Comment by info@mrdoob.com, Mar 30, 2009

Does that work on FP9 and FP10? As far as I know there was a method for FP10 that did that already, wasn't it?

Not sure about having version specific things on this little app is what I mean.

Something Tim Knip suggested is to be able to add custom fields. Seemed interesting enough to think about adding it for the 2.2.

Still, it needs to keep being simple, cpuless, and tiny. Somehow :)

Comment by j...@lacedinteractive.com, Apr 07, 2009

Hi, Mr Doob.

It's very important that you mention the memory increase issue at the top of the page. Many people will potentially lose precious time trying to find the source of this problem in their own code, when it's actually an issue with the FPS meter.

About the issue:

If you run the fps meter in a empty movie you can see that the garbage collector is not able to recycle 100% the variables generated during the fps meter operation cycle, and therefore a tiny increase in total memory usage will occur after each clean up.

Since the increase is tiny, I'd classify it as an annoyance rather than a bug, still I suggest you mention it on the page.

Thank you for this wonderful software.

Comment by info@mrdoob.com, Apr 13, 2009

I've done tests of instantiating the stats 1000 times and I wasn't able to spot any memory leak.

Some times the GC doesn't clean 100%, and takes 10 or 20 actions until it goes back to the original memory level.

Comment by christian.pfeiffer.k, Jun 23, 2009

Thanks!

Comment by matt.montag, Jul 09, 2009

Thank you Mister Doob.

Comment by adrianparr, Aug 13, 2009

How do you use the Themes?

Could you provide an example?

Comment by qubero, Aug 30, 2009

huihuicn.xu's onRemovedFromStage() seems to have disappeared in v2.1 (AS3). Stats needs to remove listeners when it's taken off stage, or else it crashes (because stage becomes null, and stage is used in fps calculations).

add this line to the end of init():

    addEventListener(Event.REMOVED_FROM_STAGE, deinit); 

and add this function:

    private function deinit(e : Event) : void {

        removeEventListener(MouseEvent.CLICK, onClick);
        removeEventListener(Event.ENTER_FRAME, update); 

    } 

You could also copy stage into an instance variable during init private var _stage:Stage and use that instead of the actual stage, if you're a belt and suspenders sorta guy.

Comment by manimalcruelty, Oct 14, 2009

love this, thanks :)

Comment by tajolly, Oct 16, 2009

Have just noticed that the memory usage of the .swf within the IDE is effected by other open .fla files, was initializing around 170mb with 2 windows open, closed 1, and now its running at 27mb

On a lighter note, cheers for the stats, very helpful!

Comment by t...@alternativagame.com, Nov 01, 2009

And no words about Alternativa... What a shame! :)

Comment by ricardo.cabello, Nov 01, 2009

Check out the header of the .as: "Shameless ripoff of Alternativa's FPS look :P"

Comment by blog2t, Nov 06, 2009

I've added my custom feature – the visibility toggler, switches the stats visibility on/off (always brings to the top when turned on) with the slash "/" key. Enjoy!

Kicks in at init()

if (stage) stage.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown, false, 0, true);

Gets disposed at destroy()

if (stage) removeEventListener(KeyboardEvent.KEY_DOWN, keyDown);
private function onKeyDown(event:KeyboardEvent):void
{
	if (event.charCode == 47) visible = !visible; //slash
	if (visible) parent.setChildIndex(this as DisplayObject, parent.numChildren - 1);
}
Comment by blog2t, Nov 06, 2009

Was also thinking to draw lines instead of dots, could be done with graphics.lineTo at LOW stage quality (no anti-aliasing).

and btw. thanks for the great tool Ricardo, I've been using it for ages now!

Comment by ricardo.cabello, Nov 06, 2009

On my projects I usually have a DebugView? class that incorporates the Stats and Logger (a class that I'll release soon). It's on DebugView? I add the keyDown handler.

Using graphics.lineTo (and changing the stageQuality) doesn't sound too good to me. People won't like to have their stageQuality changed, and lineTo would affect a bit the performance. Pixels are fast.

The idea of the class is to keep it basic to just what it needs. Sometimes people think that a feature is essential, but it's usually a very subjective opinion. That feature could be implemented outside. Many people has always said that the Stats needs a method to be able to auto attach to the right side of the stage...

Anyway, thanks for the suggestions, and happy to hear that you find it useful :)

Comment by blog2t, Nov 06, 2009

The low stageQuality suggestion was only to make the lines aliased, but it doesn't matter :) then also the bitmap scroll value would need to be 10 or so to see the difference... Sometimes I find dots too close to each other and it's then hard to know what's going on. Moaning hehe, I can obviously make the changes for myself, you're right, keep it simple.


Sign in to add a comment
Hosted by Google Code