Profiling your .NET code
Profiling gathers information about an executing application, allowing you to determine those improvements that are required in your application. Profiling is overlooked or not performed on applications despite the fact that it can have a massive benefit to the performance and scalability of these applications. This article starts with a “Top 10” list of reasons why you should give careful consideration to the task of profiling your .NET code. It then introduces the two basic tools that will get you started with this task, namely the CLR Profiler and Perfmon.
Ten reasons why you should bother profiling your .NET code
1) Focus on portions of your .NET code that really require attention
Profiling allows you to focus on critical sections of your .NET code. When you have a very large application it is very difficult to identify areas in your .NET code that require improvement. Profiling your application will pinpoint .NET code sections that really require improvement or tuning.
2) Identify code blocks with performance issues
Performance is a very hard thing to measure and trace. The task of identifying code blocks or methods that have performance issues is tedious. Profiling your .NET code helps you to identify those code lines, blocks or methods that require performance improvement.
3) Compare alternative approaches
During your development, you might come across alternate ways of achieving a task. For any given task you might have two different implementations that you wish to compare, in order to find out which implementation is better in terms of performance, scalability, and resource usage. By comparing your different implementations with a profiler, you can select the most efficent code block.
4) Get accurate code execution response times
Often, when you examine the performance of your application, you will want to find out how long a line of code, or a block of code, or a method, takes to execute. By profiling your .NET code you can get accurate execution times.
5) Avoid guessing performance issues
Have you ever looked at your application and felt that it is executing slower than usual? You cannot just go by your instinct and start making changes to your application. By profiling your application, you can confirm whether performance issues exist in your application, and where those issues are.
6) Visualize performance and memory usage
A visual depiction of execution times and memory usage for your application helps you to make informative decisions very quickly. Once you have the means to see a graph of the execution times or memory usage, it is much easier and quicker to understand issues and fix them.
7) Track the lifecycle of your .NET objects
You might be using a resource intensive object in your .NET code. Tracking the lifecycle of your .NET object will allow you to make optimizations in your code. For example you might be creating the resource intensive object too early in your application. Profiling will uncover these issues.
8) Avoid unnecessary loading or initialization of your program
During development of your application you might have had some tests that are loaded and initialized. Prior to deployment of your application you will want to ensure that any unnecessary loading or initialization is removed. It would be very difficult to track such portions of your application without profiling it.
9) Optimize your looping constructs in .NET
Looping constructs are a common source of performance issues. Profiling your code allows you to understand and eliminate unnecessary loops within your looping constructs. Improving your looping constructs in turn will improve the overall performance of your .NET application.
10) Identify memory leaks in your application
Memory leaks in your application can be very difficult to identify. Profiling your .NET code allows you to identify any unnecessary memory usage and therefore optimize the memory usage in your .NET application.
How to profile your .NET code
Now that we have looked at some compelling reasons to consider profiling, let us look at a couple of the basic, free tools that allow you to profile your .NET code.
The CLR Profiler is a free application that allows you to profile Windows applications, ASP.NET applications or services. You can download the CLR profiler from here. Once you have downloaded it, you can extract it and run the CLRProfiler.exe. When you run the CLR profiler your code will appear to execute slower than usual since your code will be instrumented to analyze the performance.
Let us create a simple Windows application and then analyze it using the CLR Profiler. You can create the following method as part of your application and invoke it (you can download Visual C# 2008 Express Edition from here – direct download link):
public void CodeToProfile()
string str = string.Empty;
for ( int i = 0; i < 2000; i++)
str = str + "|" + i.ToString();
Start the CLR profiler, and you will see the following initial screen:
Selecting “Allocations and Calls”, allows us to profile the methods as well as memory usage. You can click on “Start Application” and select the Windows application we created. The CLR profiler will load the Windows application and you can execute it to call the method we wrote earlier.
When you close the Windows application, the performance of the application is analyzed and a summary screen is presented:
You can drill into any specific areas on the performance. For example, if you want to find out how much memory was allocated on the Heap, you can click on the “Histogram” for Allocated Bytes, in the summary screen. The View menu in the main CLR profiler screen also includes menu items for the options you see on the summary screen for your application.
The above screen shows that a large amount of memory is being allotted for the strings, since we are doing concatenation and each concatenation is creating a new string instance. Let us save the current profile results.
To fix the above problem, let us replace the string concatenation with a StringBuilder. So, our new method implementation looks as follows:
public void CodeToProfile()
StringBuilder str = new StringBuilder();
for ( int i = 0; i < 2000; i++)
Let us go through the steps of profiling the application again. After profiling, the “Histogram by Size for Allocated Byes” screen looks as follows:
You can see that the memory allotted is considerably reduced using an alternate implementation.
Another tool you can use to analyze the performance of your application is the PerfMon (Performance Monitor). This tool is available as part of Windows Administrative tools and contains performance counters to analyze various aspects of your application. For example, in Windows XP, navigate to Administrative tools and select Performance. This will start the Microsoft Management Console for PerfMon.
The initial view shows the System Monitor monitoring a few performance counters for the entire system. To monitor .NET application-specific performance, click on the “new” option on the toolbar. This will clear the current view and you can add performance counters for the specific aspects for your application
To add a performance counter, click on “Add”. This brings up the “Add Counters” interface that allows you to add a performance counter. PerfMon contains a lot of counters that are specific for .NET applications. For example, to monitor the memory allocated on the heap for your .NET objects, you can select the .NET CLR memory Performance object and then select the “# Bytes in all Heaps” performance counter. If you want to monitor all .NET CLR memory related counters, you can select “All counters”. You can also select a specific instance or application for which you want to monitor the .NET CLR memory.
This creates a graph that will show any spikes in the view when you execute your application. This allows you to graphically visualize the memory usage while you interact with your .NET application. If there are any unusual spikes while executing your application, you can try improving your code and running the application again while monitoring the performance in PerfMon.
Other than the .NET CLR specific performance counters, you also get a lot of counters that are specific to ASP.NET web applications. For example, you can have a view that shows the total requests that failed for the ASP.NET application against the total requests received, and also monitor how specific resources such as memory were used when the number of requests is high.
Profiling your .NET code is a very important task in ensuring your application performs as expected. This article shows 10 reasons why you should seriously consider profiling your .NET code and then explains how to use the CLR profiler and the PerfMon tools.