With as often as I write code that does not perform as well as I would like for it to, I can’t believe how hard it is to write slow code on purpose! My last post gave a mile-high overview of the new version of Redgate’s ANTS Performance Profiler and promised more detail to come. True to my word (this time), this post aims to take a fairly simple application with common “opportunities” and use ANTS Performance Profiler to quantify these opportunities and measure the results. If you’re working along at home, I’ll provide the solution files and you will need to provide an environment where Visual Studio 2010 (I use Ultimate, but in this case any SKU should be fine), Redgate ANTS Performance Profiler (see my previous post for a link to the trial version), SQL Server Compact Edition 4.0, and the Visual Studio SQL CE Tools are installed. To make it easy to get up and running, the solution uses the Code First approach for Entity Framework and will create the database and test data if they don’t already exist, so you will probably want to start by running the solution without measuring anything so this creation overhead doesn’t skew your measurements.
Our project centers around the need for a console application to list events that occur within a given month. The takes a date, and then lists all the days that occur within the same month and and events that may be scheduled on that date. The data model is pretty simple and looks like this:
This post isn’t (overtly) about Entity Framework, so I won’t get into the gritty details on creating the entity objects and their associated object context, but please do peruse the code. The starter solution can be downloaded at https://skydrive.live.com/redir.aspx?cid=0adb9450bcc3d727&resid=ADB9450BCC3D727!370&parid=ADB9450BCC3D727!369
Once you’ve downloaded the solution, open it up, run it, and poke around a bit. When you’ve got an idea of how things work, let’s start a profile session. From the ANTS menu in Visual Studio, click “Launch ANTS Performance Profiler”
Use the settings from the screenshot below to model your settings and then click “Start Profiling”
The app will run and a few seconds later, you’ll be presented with the profiling results. There’s a lot of great information here, but this is intended to be a quick and dirty on how quickly we can make your app faster, so we’ll cut straight to what I see as the shortest path to measurable gain. The bottom pane of the results window shows the source of your application as below:
The key pieces of information in this view to help you make decisions are the Hit Count, which tells you how many times each line of code was hit, the Avg Time (%), which tells you on average how much of the overall run time each time the line of code executed took, and Time (%), which tells you the percentage of the run time that the cumulative executions of the line took. In the right-hand column, clickable colored indicators allow you to quickly zoom in on the lines of code that take the most time.
While not the most cumulative execution time, a quick and easy optimization that jumps out is the code at line 28. The metrics we’re given by ANTS shows that this line was executed 150 times, each execution took an average of .053% of the total execution time, and the cumulative executions took 7.9% of the total execution time. In other words, since the code could be rearranged to have the context instantiated only once, 7.9% of the run time is spent accomplishing what could be done in .05%. I’m given clear direction that a measurable gain can be had by moving the instantiation of the context out of the loop. When I move the code outside the loop and re-execute, the new profile tells me that this line no longer has any significant impact on the performance profile.
There are some other obvious places where optimization can be applied such as executing a query for each day instead of the entire month, so give them a try and see how the profile results shift. Just remember you can never get rid of your worst performing line of code because something will always hold that distinction.
The purpose of this post and my previous post on this subject was to encourage thinking about taking a measured approach to optimization and to demonstrate how easy Redgate ANTS Performance Profiler makes this. We’ve only brushed the surface of the capabilities of the tool, so if I’ve peaked your interest be sure to check out the features and tutorials available at Redgate’s site (http://www.red-gate.com/products/dotnet-development/ants-performance-profiler/)