Skip to content

October 17, 2007

16

An AS3 profiler

NOTE
This post has been previously published on 2007/Oct/17: due to my move to another server i’m now in the process to manually recover the comments for this article.
Fixed!

I’m currently working on an early-stage, more of a proof-of-concept thing, but i needed to know more about the code performances: googling for an ActionScript profiler just showed up ASProf, an AS2 profiler. So i decided to port to AS3 the C++ profiler i wrote for Aqua, the cross-platform framework i was working on until April: the original C++ implementation has been developed after being inspired by an article of Steve Rabin in the Game Programming Gems 1 book, that’s a nice one to have on the shelf together with some other great books of which i could post something about them later.
It is always wise to remember that if you are serious about code profiling, you’ll be better to search for some professional tools: in the C++ arena my choice would be this one, but if you plan to have lunch and dinner for the next couple of months give Eletric’s one a try, it really deserves a look.
Unfortunately for the AS3 world, i just haven’t found anything really usable for it up to now, so i just thought to release it under a zlib/png license and some hints on how it works here.

ProfilerConfig.Width = stage.stageWidth;
ProfilerConfig.ShowMinMax = true;
prof = new Profiler( 32 );
addChild( prof );

Setup some custom configuration parameters and then create a Profiler and don’t forget to add it to your local render queue: the Profiler its a Sprite and it will render the results right there, all you have to do now is to profile some code:

var i: int = 0;
var it: int = 1000000;

prof.beginProfiling();

i = it;
prof.begin( "fadd" );
while( i-- ) { fRes += 1.; }
prof.end( "fadd" );

i = it;
prof.begin( "iadd" );
while( i-- ) { iRes += 1; }
prof.end( "iadd" );

i = it;
prof.begin( "fsub" );
while( i-- ) { fRes -= 1.; }
prof.end( "fsub" );

i = it;
prof.begin( "isub" );
while( i-- ) { iRes -= 1; }
prof.end( "isub" );

prof.endProfiling();

With another couple of lines of code you’ll end up with something like this:

Cool graphing for your function-timing needs ;)
And this is it!
A thing i may point out is that you can always group code fragments belonging to your most logical schema by wrapping the same ProfileNode around the different fragments; here i’m grouping math operations by their type, just to keep the call-graph a little bit organized:

var i: int = 0;
var it: int = 1000000;

prof.beginProfiling();

i = it;
prof.begin( "float", true );
prof.begin( "fadd" );
while( i-- ) { fRes += 1.; }
prof.end( "fadd" );
prof.end( "float" );

i = it;
prof.begin( "int", true );
prof.begin( "iadd" );
while( i-- ) { iRes += 1; }
prof.end( "iadd" );
prof.end( "int" );

i = it;
prof.begin( "float", true );
prof.begin( "fsub" );
while( i-- ) { fRes -= 1.; }
prof.end( "fsub" );
prof.end( "float" );

i = it;
prof.begin( "int", true );
prof.begin( "isub" );
while( i-- ) { iRes -= 1; }
prof.end( "isub" );
prof.end( "int" );

prof.endProfiling();

That’s all there is to it, hope it will be useful!
Grab the Profiler here and take a look at the demo code used for this post.

Read more from as3, dev
16 Comments Post a comment
  1. Mister Troll
    Dec 12 2007

    Hi,

    I’ve tried your profiler, found bug but it is very usefull. Thanks.
    There is a problem with levels and parentNodes when recursion occurs.

    Thanks again, it’s a good job.
    Mister Troll.

  2. Manuel
    Dec 13 2007

    Ehi thank you for reporting that: i’ll give it a look at it but if you modified to work with recursion too i’ll be glad to publish your version since i’m quite busy; it should detect a recursion by looking up the node’s name and forcing “end”-”begin” calls but what do you expect to be represented graphically?

  3. Oct 25 2008

    Damn useful. I made some changes here:

    Public Class ProfilerConfig { …
    public static var GlobalProfiler:Profiler = null;
    }

    so I can use this:
    ProfilerConfig.GlobalProfiler = new Profiler(32);
    addChild(ProfilerConfig.GlobalProfiler);

    So now ProfilerConfig.GlobalProfiler will be the same across all the classes in the project.

    Thanks for building this great system! I wanted to diagnose performance bottlenecks and planned on writing something similar. Finding yours saved me tons of time! Well done. Also, nice interface – better than I would have done.

  4. Dec 8 2008

    Thank you for a wonderful tool!

  5. bubba
    Jan 30 2009

    pretty l33t tool

  6. nathan
    Feb 6 2009

    Thanks for this, very nice!

  7. Mar 28 2009

    Wow! This tool is just what I was looking for. It took some googling and you were near the bottom of the first page, but I’m glad I kept checking out the links to find this.

    Thank you very much for releasing this to the as3 community.

  8. Mar 28 2009

    So, I’ve been using this a bunch now and have a few questions if you have time to respond:

    First, I have followed your demo code to learn how to use it in the context of a larger application, a game in this instance.

    1) When using this tool to test out the performance of a game do you recommend making the calls to ‘prof.beginProfiling();’ and ‘prof.endProfiling();’ at a higher level and in a central location (like an enter frame event etc) so that they are opened and closed once per frame while you may have many other calls to individual tests with ‘prof.begin(“blah”);’ ‘prof.end(“blah”);’ at lower levels that it accumulates data from?

    2) Should the initial call to prof = new Profiler( x ) have x = FPS of your game fla?

    3) I see that in the code for the profiler there are statistics tracking of min and max times. I have read the code and see how you are using it in certain areas and in the displaying of the min/max bar graphics options via optional ProfilerConfig.showMinMax call, but would love to be able to add a max column number to the output because while I am testing my app on the fly it isn’t as useful when the time data keeps dropping to 0ms when I’m not actively in the test being tested. I need to be able to see my max times or avg times at least over the duration of a program to make educated guesses as to where to improve it. With this context in mind, is this already supported and I just don’t see it? Is this something that you feel wouldn’t be too hard for me to hack in there? I just wanted to see if you had any recommendations on how it would be done as the author before I dove into your code to hack it up for myself. :)

    Thanks again, I’m having a blast using this program and getting some good data from my game performance!

  9. Manuel
    Mar 28 2009

    Hi Hybrid,

    if you don’t mind i’ll respond to your questions publicly so that other people may find that useful.
    Before responding, you may want to know beforehand that this tool was adapted to work in AS3, but i originally developed it for profiling the framework i was working on and the application i needed to profile was exactly a game, so it seems our needs are quite related to each other one ;)
    As for your questions, here we go:

    1) indeed you’ll be more comfortable in wrapping deeper-level calls in a singly-rooted one-node call that can embrace all of your deeper calls. For instance, the game i was profiling was a tick-based event system (a quite common one): the main “onTick” function was being called once for every frame, say 32 times per second, and it was dispatching the tick event all along the chain of objects i had.
    As soon as you enter the “onTick” call you want to “beginProfiling”, perform your operations and then “endProfiling” as soon as you exit the function.
    Now that you are basically timing every frame from start to finish, you may want to time more deeper, slicing the original root via begin/end: you have to be sure the slices you define (begin/end) are common to the same root or your results will end up to be partial or cumulative and not related as they should.
    The “onTick” function i’m talking about can be perfectly seen as the AS3′s “onEnterFrame” event, you just have to make sure everything live and die between every call: profiling code that lies outside that is another matter, you just can’t relate it to useful values since you can’t have a common root for that: you can, however, process asynchronous events in your “tick” call, so that async-calls just modify some data that you actually “look-at” it just once per frame. If you want more information on that we may switch to private mail, just let me know.

    2) i should have specified that in the sources, the number you specify is basically the number of frames you want to accumulate data from before computing stats: although generally “the more the better”, i personally settled on the fps you are actually updating everything so that whenever i look at the stats i’m in fact looking to the performance of the computations performed in the last elapsed second.

    3) that’s what i always wanted to add and never had the time to implement it: it shouldn’t be hard to hack those into the profiler, most of the data is already there, you’ll just have to hack around the rendering, feel free to do any hack you want to it, in fact i really encourage you to do it: if you are writing a game you’ll be surely able to find your way into the Profiler and add what you need.

    Thank you for using it and (possibly) enhance it!

  10. Apr 1 2009

    Manuel,

    Thank you so much for the reply! Everything you mention makes good sense so thanks for the clarifications. Yes, after studying the code a bit more I see how it wouldn’t be that hard to add that functionality I was requesting. I have also been using the ability of flex builder 3 to profile an external flash application that has been quite nice as well. It isn’t really an option for people that don’t have flex, but for those that do it gives some great output. Are you familiar with that at all? I discovered this link here that has info on a presentation and the simple steps to get it working. Just thought I’d share in case you or others were curious about using some of the low level tools available in Flex. Anyway, thanks again for your software!

  11. Manuel
    Apr 1 2009

    Cool thing you can actually debug non-Flex builder projects, i didn’t know that: i used the Flex profiler in the past when i was working at Jooce, indeed it’s a great tool for debugging flash-based applications, especially for looking at memory leaks and observing the garbage collector cycle.
    Thank you for sharing it, nice tip worth to mention!

  12. Annie
    Apr 15 2009

    Hi Manuel,

    When I used the demo, I met one error:

    TypeError: Error #1007: Instantiation attempted on a non-constructor.
    at profiler::ProfilerResources$/createFixedTextField()
    at profiler::Profiler$iinit()
    at demo$iinit()

    The problem is the following line:
    private static const fixedFont: Class;

    I made fixedFont a class:

    package profiler {

    import flash.text.Font;

    [ Embed( source = 'assets/fleftex.ttf', fontName = 'fixedFont', mimeType = 'application/x-font-truetype' ) ]
    public class fixedFont extends Font {}

    }

    and delete:

    [ Embed( source = 'assets/fleftex.ttf', fontName = 'fixedFont', mimeType = 'application/x-font-truetype' ) ]
    private static const fixedFont: Class;

    in ProfilerResources.as.

    Then the error disappeared.

    But when I run it, I can only see the graph, I can not see any words on the swf.

    I dont know why.

    sorry ,maybe my question is a litter stupid .I am the AS3 beginner.

  13. Annie
    Apr 16 2009

    sorry, I used Flash CS4 this time, it works. thanks.

  14. Annie
    Apr 16 2009

    Hi again,

    I have another question, now I can use the profiler to test code fragment, how can I use it to test functions or classes?

    Thanks in advance.

  15. Aaron
    May 17 2009

    This is a great tool :)

    I have been looking for a profiling tool for flash for a while.

    I’m making a game which is becoming pretty large in terms of LOC and this is going to be invaluable in improving performance. =D

Trackbacks & Pingbacks

  1. How to make Angry Birds – part 2 | Paul's blog@Wildbunny

Share your thoughts, post a comment.

(required)
(required)

Note: HTML is allowed. Your email address will never be published.

Subscribe to comments