There comes a time in a software developer’s life where his code becomes slow. Sometime it is even possible to state the exact revision or date that caused the performance decrease. Searching the source code for the usual suspects can be futile and frustrating, and then there is the tricky part of making sure the performance issue has been solved after a change has been made.
Don’t get me wrong – understanding code is a must, but there is much more to performance tuning then just reading the code searching and solving each “suspect” as discovered. I’ve witnessed many times a lot of effort being made to optimize a part of the code that was only called once in a moon.
Performance Analysis is the first order of business before an attempt of any optimization can be made.
There are a lot of tools in the market for exactly that purpose - to find where the application spends most of its time and the component (or components) that are responsible for most of the bottlenecks in the runtime.
In the (near?) future I plan to write a review of the available tools but in this post I’d like to address a different aspect of performance analysis – using simple benchmarking for research of alternatives once the performance hot spot has been discovered.
In .NET there are some well known performance pitfalls:
- Needlessly using boxing/unboxing of value types when calling functions or while using object based collections (ArrayList, Hashtable etc.).
- Multiple consecutives calls to WebServices to do a simple task.
- Abuse of Database – a lot of reads and writes
And the list goes on…
Then only list bigger then that list is the list of possible Solutions. To determine which solution is better and even do small scale performance analysis a simple benchmarking would suffice.
In the past (.NET 1.1) I needed to create my own “high precision timer” using interop and CPU related Voodoo but since .NET 2.0 I throw all that away and use StopWatch for all of my benchmarking needs.
StopWatch intelligently uses a resolution based on whether the underlying hardware supports a high one or not, if not supported (not likely in computers from the last couple of years), the Stopwatch reverts to that provided by DateTime.
Using StopWatch is very simple:
- Create a new instance of StopWatch
- Use Start() and Stop() before and after the code under invetigation
- Use Elapsed property to retrieve the time that passed.
Stopwatch stopWatch = new Stopwatch();
// Run your code
// Get the elapsed time as a TimeSpan value.
TimeSpan ts = stopWatch.Elapsed;
In order to get accurate results I suggest running the code multiple times (i.e. 1000) to reduce “noises” and ignoring the 1st result that could be affected by the initial JITing of the code under test.
After a while of benchmarking my code I learnt very interning performance improvements and pitfalls in the .NET and how much they effect my application.
As a matter of fact I used stopwatch for determining the performance difference between List<T> and ArrayList .