I’m going to switch gears here for a post or two and talk about software profiling. For those of you who have never used a profiler before, or have no idea what I’m about to talk about, here’s a quick run-down:
A profiler is an add-on program that will measure the performance of your code. Typically, this software allows the developer to drill-down into slow sections of code to see what is hogging all the CPU cycles. One package I’ve used in the past, and is an excellent profiler, is Redgate’s Ants profiler. It’s worth every penny. However, if you’re like me, you have a limited number of pennies to throw around (yes, Ants is a bit on the pricey side). So I’m always on the lookout for something cheap but easy to use. This is where MiniProfiler comes in.
Miniprofiler is easy to install. It took me about 15 minutes to install it into a demonstration MVC4 application. If you go to the MiniProfiler website: http://miniprofiler.com/, you can follow the directions step-by-step. Use the NuGet package manager to get the versions of MiniProfiler that you need.
For a generic MVC4 program, you’ll need the following setup steps:
- Install the NuGet packages for MiniProfiler (PM> Install-Package MiniProfiler), the MVC package (PM> Install-Package MiniProfiler.Mvc4), and if you are using Entity Framework 6 (PM> Install-Package MiniProfiler.EF6 -Pre). There is also a package for NHibernate (which I will be testing in a future post). I discovered the NHibernate version when I typed “miniprofiler” in the search box of the NuGet package install window.
- Next, just like the instructions show you on the MiniProfiler.com website:
@using StackExchange.Profiling; ... @MiniProfiler.RenderIncludes()
Obviously, in an MVC application, the head and body tags are not shown. Just declare the using statement at the top of the view and put the RenderIncludes() method at the bottom.
Add this to the global.asax file:
using StackExchange.Profiling; protected void Application_BeginRequest() { if (Request.IsLocal) { MiniProfiler.Start(); } }
I also added this:
protected void Application_EndRequest() { MiniProfiler.Stop(); }
One last thing for the setup, open your Web.config and add this:
<system.webServer> <validation validateIntegratedModeConfiguration="false" /> <handlers> <add name="MiniProfiler" path="mini-profiler-resources/*" verb="*" type="System.Web.Routing.UrlRoutingModule" resourceType="Unspecified" preCondition="integratedMode" />
Now you’ll need to add some “using” statements to your code if you expect to profile sections of your code.
var profiler = MiniProfiler.Current; // it’s ok if this is null using (profiler.Step(“Title to show for this code“)) { // your code goes here }
OK, now run your MVC4 program, and you should see something like this:
You’ll notice in the upper left corner of your browser will be a tiny button with the time it took to execute your code. Click on this button and you’ll see something like this:
You can click on the “more columns” to see more detailed information about the profile. In my example MVC4 application, I used a controller named Home with a view named “Index”. I also put “Read person list” inside my profiler step title, which took 20.2 ms according to the information above.
OK, now, you can decorate your program with “using” statements to wrap each granular section of code in a profiler step. Then you can turn off your profiler by controlling the MiniProfiler.Start() method in the global asax.
Adding Entity Framework Support
Install the MiniProfiler using NuGet
(PM> Install-Package MiniProfiler.EF6 -Pre)
Now open your Global.asax file and add the following using statement to the top:
using StackExchange.Profiling.EntityFramework6;
Add the initialize method to your Application_Start() method (this method should already exist):
protected void Application_Start() { … MiniProfilerEF6.Initialize(); }
Run your program and you should see an additional column of numbers for your sql calls (assuming you setup an EF6 data context and called a query that is wrapped in a miniprofiler step):
Notice the links in the sql column? Click on one of these and you’ll get a break-down of what was executed:
ReadAllrecords is a method name that I created to read records from a table called “person”. The first entity framework query looks like this:
var query = (from p in db.people select p.first).ToList();
and the second query looks like this:
var query = (from p in db.people select p).ToList();
The profiler spits out the actual SQL that was generated by my LINQ queries, which can be convenient to determine what is going on at the SQL server level. You can also copy the SQL text and execute it in the MS SQL server console window to verify what is going on.
Next time, I’m planning to try out the NHibernate version. I’ll be setting up a demo NHibernate project, populate with a large list of data (maybe I’ll copy one of my previous NHibernate projects) and I’ll show how the MiniProfiler behaves.