Measuring game performance : framerate is not everything

I am currently having a few problems with performance in Spring Up XNA. I have two features that are too expensive in processing power : the background effect and the computation of the preview trajectory of the ball.

I know these features are not usable at this cost because as soon as I activate one of them, my framerate drops and the game does not run at 60 FPS. When your game runs at 60 FPS, everything’s fine. When it does not, how can you tell how “far” you are from it. And because XNA is trying to catch up when your game is slow, this is even more obscure (there is a very good article on Shawn Hargreaves Blog about this topic called Understanding GameTime).

fpsTherefore, in order to have accurate and useful performance information in real-time , I am displaying on screen the time spent to compute and draw the last frame, in milliseconds.

This is done easily using the Stopwatch class. This class is standard C# system library, it is not part of XNA. It is very easy to use:

stopwatch.Reset();
stopwatch.Start();
// Code to time here
stopwatch.Stop();

You just have to time the whole Update and Draw functions. Then you can read the number of milliseconds directly in the ElapsedMilliseconds member of Stopwatch. However, as this value is a long type, I prefer to compute the number of millisecond more precisely using this code:

(float)StopwatchUpdate.ElapsedTicks/(float)Stopwatch.Frequency*1000.0f

And to display it properly, I use the following formatting:

string fps = string.Format( "fps:   {0:00.0}nupdate:{1,4:00.0}n
draw:  {2,4:00.0}", _fps,
(float)StopwatchUpdate.ElapsedTicks/(float)Stopwatch.Frequency*1000.0f,
(float)StopwatchDraw.ElapsedTicks/(float)Stopwatch.Frequency*1000.0f );

I first thought that the numbers would change so quickly that it would not be usable but it’s pretty constant in my game. I can see huge differences when disabling some GameComponents. It is also useful to see if you spend more time in the update part or the draw part. You must have separated game logic and rendering properly, of course.

I told before in this blog that you must not spend time optimizing when you do not need too. But having this few lines of code is harmless and can be useful while adding new features:

  • If you see that you spend 5 more milliseconds in this session than in your previous one, you may need to have a closer look at this new code.
  • As Spring Up XNA is heavily using dynamics (through BOX2D), I can also compare the performance of the different levels.
  • You can see when a single frame takes much longer to update/draw (choppy framerate).

Hope this helps!