Av rating:
Total votes: 15
Total comments: 0


Ryan Garaygay
Using a Profiler to Speed Application Performance
27 February 2009

Use a profiler to measure before you optimise. If ever you doubt this advice, then you should read this fascinating account of how an application was given a five-fold speed increase just by finding out exactly where the performance problems were and then tackling them in detail.


We now get through
the full 9 million rows
in 2-3 days –
at least 5 times faster!

                 ”

As part of our company’s business intelligence, marketing effectiveness platform (including a high-scale contact relationship management application) is a system which uses SSIS (among other things) to extract, transform and load huge amounts of data from a wide range of different sources. Once it’s all in a central SQL Server database, a background C# batch processing application works through the data using highly complex grouping and clustering algorithms to analyze and make the data consistent. Somewhat similar to SSIS fuzzy grouping but we had extra considerations and needed more control on the process.

Agilone AGLX platform

When this was taking weeks rather than days we knew we had a problem and that was when I got more involved in the project. It’s fine if this task takes up to a week to process all the data (currently around 9 million rows for example in one of our clients), but it was now taking this long to process less than half the data!

Bringing in a profiler

I initially started inserting timing code throughout the code, but this is obviously very tedious, and can be inaccurate. Worse, you depend on guesswork to work out  where to effectively insert code. I quickly realized I needed proper non-intrusive profiling.

A quick Google search showed up a shortlist: dotTrace from JetBrains and ANTS Profiler from Red Gate. Although I love JetBrains’ Resharper, I found ANTS Profiler was more usable at taking me down to which methods and which lines were taking the time plus being able to look at those lines in the same window. That is without going back and forth from Visual Studio

The analysis proved to be an incremental process. Each time, I would work down from the method level timing and find the top bottleneck. At first, the bottlenecks turned out to be data access, so I used SQL Profiler and Database Tuning Advisor to work out the necessary DB and query changes.

5X performance gains (or more)

This still left performance problems in the C# code itself. Assuming that the quickest way to get a major improvement was to change the core algorithms, I tried rewriting some of the fuzzy grouping algorithms – this made the code a lot more complicated, but turned out to make almost no improvement to performance. As ever, before you optimize, always measure. So I reverted the code, and went back to ANTS Profiler again.

Surprisingly, some of the major problems turned out to be the simple things – regexp and String performance, and basic collection types. A couple of changes in the string handling*, and using hashtables instead of lists (Hashtable is faster than SortedDictionary, SortedList or List), and we now get through the full 9 million rows in 2-3 days – at least 5 times faster!

ANTS Profiler results before optimization.

ANTS Profiler results after optimization.

Lessons learned

In retrospect, the lessons are fairly obvious:

  • Use a profiler to measure before you optimize – it really sucks trying to optimize something only to find out that it is not the bottleneck.

  • Use the appropriate DB tuning tools.

  • Keep measuring – it can be the simple things that are causing the problem.


* <string>.SubString(...) does some considerable lifting, so if you want to check if the first two chars in a string are equal to some other string then you should consider using <string>.StartsWith instead or avoid the SubString if you can.

Code before optimization.

Code after optimization. 

Note: Although it is generally not recommended to place a dictionary as hard-coded values, the stakeholders in this project have specific reasons for doing so.

Also profiler screenshots provided was made only against a subset of the data.

Download your free trial of ANTS Profiler here.



This article has been viewed 7343 times.
Ryan Garaygay

Author profile: Ryan Garaygay

Ryan Garaygay is a software developer employed by LWSMedia Philippines and works for Agilone LLC, an analytical consulting and technology services firm based in the US and Turkey. He works on various web and desktop projects .NET and SQL Server technologies with particularly interest in performance optimization, debugging, security and business intelligence. He holds MCSD, MCPD and MCITP certifications and in those rare free times shares his experiences at http://ryangaraygay.com/blog

Search for other articles by Ryan Garaygay

Rate this article:   Avg rating: from a total of 15 votes.


Poor

OK

Good

Great

Must read
 
Have Your Say
Do you have an opinion on this article? Then add your comment below:
You must be logged in to post to this forum

Click here to log in.
 






recommended site pinvoke

PInvoke.net is a user-driven wiki which provides .NET developers with native method signatures, so they don't have to spend time writing them from scratch.




Has .NET Reflector Saved Your Bacon?
 We think Reflector is a fantastic tool, and we know you do too. We'd love to hear about the times... Read more...

The Managed Heap
 Because Red-Gate's .NET team works closely with the users of their products in order to try to fit the... Read more...

Using Three Flavors of LINQ To Populate a TreeView
 LINQ is a valuable technology. LINQ to XML, LINQ to Objects and LINQ to XSD, in particular, can save... Read more...

How to build a Query Template Explorer
 Having introduced his cross-platform Query Template solution, Michael now gives us the technical... Read more...

How to Create Event Receivers for Windows SharePoint Services 3.0
 You'll be surprised how often that you'll use event receivers instead of Workflow in order to implement... Read more...

A Complete URL Rewriting Solution for ASP.NET 2.0
 Ever wondered whether it's possible to create neater URLS, free of bulky Query String parameters?... Read more...

Visual Studio Setup - projects and custom actions
 This article describes the kinds of custom actions that can be used in your Visual Studio setup project. Read more...

.NET Application Architecture: the Data Access Layer
 Find out how to design a robust data access layer for your .NET applications. Read more...

Web Parts in ASP.NET 2.0
 Most Web Parts implementations allow users to create a single portal page where they can personalize... Read more...

Configuring Forms Authentication in SharePoint 2007
 Damon Armstrong provides a step-by-step guide to the processes, quirks and pitfalls of setting up... Read more...

Over 150,000 Microsoft professionals subscribe to the Simple-Talk technical journal. Join today, it's fast, simple, free and secure.

Join Simple Talk