First time here? You are looking at the most recent posts. You may also want to check out older archives or the tag cloud. Please leave a comment, ask a question and consider subscribing to the latest posts via RSS. Thank you for visiting! (hide this)

There has a been a lot of talking on a possible “big design flaw” in ASP.NET MVC: partial view path resolution was not cached and so a big performance issue. It all started with Rudi Benkovic’s presentation on ASP.NET MVC performances.

I also wrote a commentary on his presentation, but I was a bit skeptical about the fact that view path resolution was faster with a full url than with just the name of the view. I said:

This last one looks strange to me because the RenderPartial method should be caching the path resolution: maybe it’s a bug, or the test was performed with a pre-release version that didn’t cache the result.

But I didn’t have time to really test the behavior.

Then today another post came out: ASP.NET MVC: Hidden Performance Problem with HtmlHelper.RenderPartial functions.

He says that for each view rendered, all the search path are probed and, in order to understand whether a file exists or not, they throw an exception. This sounds silly to me, so this evening I decided to try it myself.

And I found the way to improve the performances without adding another layer of cache as someone was already planning to. Just don’t run in debug mode:

<compilation debug="false">

Yes, it’s that simple.

Since ASP.NET MVC source code is public (actually it’s OpenSource) I had a look at it. And I found out the following line:

protected VirtualPathProviderViewEngine() {
    if (HttpContext.Current == null || HttpContext.Current.IsDebuggingEnabled) {
        ViewLocationCache = DefaultViewLocationCache.Null;
    }
    else {
        ViewLocationCache = new DefaultViewLocationCache();
    }
}

This says: if you are in debug mode (or are not in a web environment, like in tests), don’t cache. Otherwise use the cache.

I also went a bit on, and added some logging inside the view path resolution, in order to run it in release mode and see with my eyes that the cache was being used. The code that follows is the GetPath method inside the VirtualPathProviderViewEngine.cs file (code truncated to enhance readability):

private string GetPath( /* truncated */) {

     /* truncated */

      if (useCache) {
        string result = ViewLocationCache.GetViewLocation(
                                          controllerContext.HttpContext, cacheKey);
        if (result != null) {
            controllerContext.HttpContext.Response.Write(
                      String.Format("{0} lookup returned {1}\r\n", name, result));
            return result;
        }
    }

    controllerContext.HttpContext.Response.Write(
                String.Format("{0} lookup no cache\r\n", name));
    return (nameRepresentsPath) ?
        GetPathFromSpecificName(/* truncated */) :
        GetPathFromGeneralName(/* truncated */);
}

If you run in debug mode you will always see, when calling the RenderPartial on the LogOnUserControl, “LogOnUserControl lookup no cache”. But if you run it in release mode, you will get the no cache message the first time you run it, and later you’ll get “LogOnUserControl lookup returned ~/Views/Shared/LogOnUserControl.ascx”.

So, problem solved, no “big error” inside ASP.NET MVC 1.0, just someone that forgot the set the debug flag to false when doing its performance testing. And innocently spread the panic around that.

Actually finding that they decided to use no cache in debug mode was difficult to discover without looking at the code, but when you do tests, especially performance test, remember to run in release mode.

There are also other reasons why you don’t want to run production or performance testing code in debug mode. Read what Tess has to say about that: ASP.NET Memory: If your application is in production… then why is debug=true

kick it on DotNetKicks.com

Technorati Tags: ,
posted on Wednesday, April 22, 2009 11:30 PM

Comments on this entry:

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Sergejus at 4/22/2009 11:57 PM

Wow, nice finding, Simone! I though that something strange is with performance results. MVC team is really confident enough to handle situations like this.

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Michael K. Campbell at 4/23/2009 12:13 AM

Simone,

Great post. And, frankly, it's kind of cool to see potential 'huge' deals in MVC. I mean... I spent sooo much time before with Web Forms hunting down oodles of different bugs and issues - only to find that in most cases, they WERE bugs and issues.

So it's cool to see that
a) we've finally found what looked to be a bug/issue
b) it was so easily squashable.

Great post.

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Gian Maria at 4/23/2009 11:29 AM

Nice post, the rule is "Never test for performance in debug mode", in debug mode a framework can really be slower. Same consideration applies to standard asp.net webform ,where script and other things gets no cached in debug model.

alk.

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Dan Swatik at 4/23/2009 2:00 PM

Wow this killed me. This confirmed a lot of my opinions about people having performance issues when I never seem to. Thanks great post

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Simone at 4/23/2009 7:59 PM

@Michael: you are right... probably the reason behind that is that MVC is so clean and simple that it's unlikely that Phil & C. missed something so obvious and bold.

I was starting to miss the bug hunting and issue resolution of the old WebForm :)

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Bret (RunXc) at 4/24/2009 8:50 PM

Hey thanks for debunking this. It seems everyone is looking to find performance issues with MVC which I can understand but it is great to get to the bottom of some of these so called issues.

# re: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Left by Simone at 4/25/2009 12:53 AM

I don't think it's bad that people are running performance test with ASP.NET MVC, and finding potential issues.
At the it was great: now we all know that it caches the view path resolution, that it's cached only for 15 minutes, and that it's done only in Release mode. Things that we didn't know before.

Comments have been closed on this topic.