Reporting performance statistics in your XNA code

Written by Dean Edis.

In our first article we covered how we can write a simplified Photoshop-style API for displaying multiple textures on the screen, and we have since extended the code to several extra features:

Adding Parallax scrolling to your XNA code
Adding video layers to your XNA code

In this article we will add a class which allows us to display a customizable collection of your application’s runtime statistics. Two of the most important pieces of information to keep an eye on during development of an XNA project are:
● Frames per second (FPS)
● Garbage collection activity (See our earlier article.)

Allocating memory unnecessarily can have a negative effect on performance, especially when targeting platforms such as the Xbox (which has a different Garbage Collection implementation that on Windows machines). Generally speaking the less garbage collection required, the better. By being able to see at runtime how many collections are being made, you can get an early ‘heads up’ on potential bottlenecks you might be adding.

Here’s a screenshot showing a video playing on one layer, with another layer showing some runtime statistics:

The first line is fairly straight-forward - It displays your current frame rate (updated every 0.5 seconds). The next few lines show the total number of 0, 1, and 2 ‘generation’ of garbage collections. The example code is fairly light on memory allocations, so it may take a short while for the counts to start increasing.

As with any other of our Layer implementations, adding this new layer is trivial. Just create an instance of the new StatsLayer, and pass in the SpriteFont you wish to use for the display. I’ve included a hand-made font based on the ZX Spectrum, as it is clear and simple. For example (from the example code you can download below):

protected override void LoadContent()
{
 m_spriteBatch = new SpriteBatch(GraphicsDevice);
 // Define each layer.
 var videoLayer = new VideoLayer(Content.Load<Video>("Animal"), true)
 {
 AutoRepeat = true
 };

 var statsLayer = new StatsLayer(Content.Load<SpriteFont>("Speccy8x8"));
 // Create a Layers object, and define the order of the layers to display.
 m_rootLayers = new Layers();
 m_rootLayers.Add(videoLayer);
 m_rootLayers.Add(statsLayer);
}

 

Feel free to add to and customize the information that is displayed. For example, in some games you might like to display the number of on-screen sprites, sprite collisions, memory footprint, debug messages, etc… To do this just extend the StatsLayer code (or make a subclass which inherits from it):

public override void Draw(SpriteBatch spriteBatch)
{
 m_frameCount++;

var s = string.Format("{0} FPS\n{1} GC Gen 0\n{2} GC Gen 1\n{3} GC Gen 2", FPS, 
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2));
 spriteBatch.DrawString(m_font, s, Vector2.Zero, Color.Yellow);

 // Add your code here.

}

You can download the full source (including a pre-built sample application showing its usage) from the link below.

DOWNLOAD SOURCE