The Joy of Performance Profiling (part 1)

Performance: it’s great. It’s a feature.  Everyone appreciates a fast application. But despite our best efforts, it’s not unheard of for software to turn out a little (whisper it)… slow.

Maybe it runs ok on your development machine, or the test environment, but once it gets out there in the wild, away from the SSDs and multicore processors, it grinds to a halt.  The problem is that whilst very few users would list “performance” as one of their most important features, a slow application has the power to drive people away in droves  - no one wants their tools to slow them down.

Waiting...

I know a lot of developers who dread the idea of working on performance enhancements, but when it’s done right it is one of my personal favourite development activities.  You have a simple aim, you get to be a bit creative and the end result (assuming you succeed) will be universally loved - from a user’s perspective, you cannot implement “faster” badly.

You can take a range of approaches when trying to improve performance but, over a number of projects, I’ve settled on a system that seems to work pretty well.

1. Focus on a single operation

If your remit is “this application is slow - fix it” then it is tricky to know where to start.  A much simpler proposition would be “this button freezes up the UI for too long when clicked - fix it”.  As with any bug (and poor performance should be treated as a bug), you need a small, repeatable set of instructions to reproduce the problem so that you can investigate the cause and test your fix.

2. Measure the problem

…or “get a profiler”.

This is far and away the most important step in improving performance.  If you don’t know what is slow there is no way you can improve it; if you don’t know how slow it is then you can’t know if you have succeeded.

Trying to track down a bottleneck without tools to measure performance is always painful, so you will need to find a  profiler to analyse where the time is being lost.  There are a number of such tools on the market, including one that comes free with Visual Studio, but my weapon of choice has always been the RedGate Performance Profiler.  The exact tool doesn’t matter too much, provided that it can observe your application and tell you how long each method (or, better yet, each line) is taking to run.  You are looking for:

  • Total time spent in the method (including children), preferably as a percentage of its calling method’s time
  • Hit count - the number of times that method was called Once you have this information you are halfway there.

3. Pick one method

Once you’ve run your test case with the profiler attache, you should end up with something like the below: a list of methods that were executed, ordered by the amount of time each took.

You are not looking for the slowest method, at least initially.  The slowest method will almost always be a high-level button click handler or page load, and will do a thousand tiny things before it completes.  If that method needs to be faster then you need to work out which of those thousand things is taking longer than it should, and then focus on that.

The ideal target method is one that has a single easily understood function that doesn’t rely too much on external resources and doesn’t have too many external effects.  Obviously this is not mandatory - if one method is clearly too slow, then that is your target no matter what it looks like -  but if you have a choice in the matter, you should probably pick GetRecordsForDate() or CommitChanges() over something high-level that does a lot of different things.

4. Make it faster

Having finally selected a method to work on, all you need to do  is…make it faster!  This is where the fun part starts, because you will need to be a little bit creative to see an improvement.  There are a few common ways that you can get some positive results, but those will have to wait until part 2