NProf : A Simple, Efficient and Free XNA Profiler (3.1 and 4.0)

Update: I have many visitors coming here from search engines. So here is a quick update if you want to use NProf with XNA 4.0. When you run NProf with your game, if the UI of NProf stays empty after running your game, it’s because you are running a XNA 4.0 game. There is a workaround here: Run NProf.exe with a .bat containing:

set COMPLUS_ProfAPI_ProfilerCompatibilitySetting=EnableV2Profiler
NProf.exe

Original post:

On its google code page, NProf is described as a statistical profiler for .NET applications. Good news: XNA being .NET, it can be used to profile games.

It’s well known that in order to optimize, you first need to find what part of your code is slow. That’s where a profiler comes handy, it finds the bottlenecks of your game and then you can optimize what needs to be.

The title of the post says it all, NProf is trivial to use, efficient and free. Once you download it, you select your XNA game executable, play it for some time and that’s it! I spent some time trying to find great profilers when I developed for PC and Mac but could not find anything really usable and affordable. I finally timed critical code sections with custom code and studied the log manually. Fortunately, NProf does all that for me in XNA.

I had a few surprises when I ran NProf. For instance, yesterday I could see that 21% of the game was spent in one method:
Color.Color( Vector3 )

This XNA constructor converts a Vector3 in a Color and it is called a lot in my game to create my background effect (see an old version in motion here). In this constructor, the expensive call is PackUtils.ClampAndRound. I do not have access to this code, but I can use another basic constructor and do the conversion myself. Here is what I ended up doing:

Before
Color col = new Color( vColor +
    new Vector3( start_val, start_val, start_val ) );
After
int r = (int)(( vColor.X + start_val) * 255 );
int g = (int)(( vColor.Y + start_val) * 255 );
int b = (int)(( vColor.Z + start_val) * 255 );
Color col = new Color( ( r > 255 ) ? (byte)255 : (byte)r,
    ( g > 255 ) ? (byte)255 : (byte)g,
    ( b > 255 ) ? (byte)255 : (byte)b );

The new code doesn’t clamp values below zero but I don’t need that feature. The really important thing is that it is now more than 12 times faster than before!

Without NProf, I would not have guessed that this constructor was that critical.

The main problem I see with NProf is that it only profiles your game on Windows and bottlenecks may be different on the X360.

Anyway, I really advise you to run your game in this profiler before you optimise anything. Be sure to use a release build.

Feel free to share your experiences with NProf!