A slightly more readable mvcminiprofiler

Published on den 28 November 2011

I think the MiniProfiler is brilliant. In fact I use it at any new project. It bothers me that the syntax is a bit clumsy out of the box though. A few simple helper methods can mitigate this.

Background

From the google code page for MiniProfiler http://code.google.com/p/mvc-mini-profiler/

*A simple but effective mini-profiler for ASP.NET MVC and ASP.NET. *

And that is what I like about it, you tell it what to profile so the overhead is low and you can use it in production and it won't alter the code. Normally when you profile the code using a full profiler like the one built into to visual studio you might see some strange results. Code is like Schrödinger's cat, you cannot observe it without changing the context. All profilers come with some overhead and atleast in the visual studio profiler the results might be plain wrong because small really cheap operations called repeatedly is slow down by the profiler to look like a significant problem in the results while they really aren't without the profiler.

MiniProfiler will also change the context but you are not going to micro profile with it. You should use it to profile if it loading the news or loading the calendar that is the slow part of your problematic page load. And because it can hook in into the sql connection and provide sql profiling it can also help you understand if the query or the deserializtion is slow when using an ORM like Entity Framework(Which has really crappy deserialization speed). 

The out of box experience

One example used on the home page:

using (profiler.Step("Set page title"))
{
    ViewBag.Title = "Home Page";
} 

Ok, so your one row has become three row, Not what I wanted but I can live with that. But what if you method returns something, like a db call for example?

Here is an example from my current project:

using (Profiler.Step("DB")) {      var course = this.courseService.GetCourse(id); }

The problem is that I cannot use that variable outside the using scope as it is defined inside. Well that is easy to fix!

Course course; using (Profiler.Step("DB")) {      course = this.courseService.GetCourse(id); }

IMO this is really annoying, I don't want my code to look like that and I certainly don't want to write that every time.

Func and Action to the rescue

The above was in one of my controllers. I always add a custom baseclass to my controllers to be able to hook in custom logic for all my controllers if I would need it. MVC 3 has global filters which could do that but I still like to have the base class.

So in the base class I add two functions:

protected TModel Profile<TModel>(string name, Func<TModel> action)
{
    using (Profiler.Step(name))
    {
        return action();
    }
}

protected void Profile(string name, Action action)
{
    using (Profiler.Step(name))
    {
        action();
    }
}

The first one is for method with return types and the second one is for methods returning void. And I use them like this:

var course = Profile("DB", () => this.courseService.GetCourse(id));

Or:

Profile("Save", () => this.invoker.Invoke(command));

As an added bonus I have removed the dependency on MiniProfiler in most of my code. If I would like to log this performance metrics some other way I would have much less code to alter.    

Then feel free to it or if you have any comments or questions mention @MikaelEliasson on Twitter.

CTO and co-founder at Bokio with a background as an elite athlete. Still doing a lot of sports but more for fun.

#development, #web, #orienteering, #running, #cycling, #boardgames, #personaldevelopment