views:

565

answers:

2

Hi, In my recent project which is using Asp.net Mvc 2, we found that the DisplayFor has performance issue. I'm not so sure whether it is the real issue or did I miss something?

I hope some Asp.net Mvc Guru can explain it to me. :)

Model.

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public string Address { get; set; }
    public string EmailAddress { get; set; }

    public static IEnumerable<Customer> GetCustomers()
    {            
        for (int i = 0; i < 1000; i++)
        {
            var cust = new Customer()
            {
                CustomerId = i + 1,
                Name = "Name - " + (i + 1),
                Address = "Somewhere in the Earth...",
                EmailAddress = "customerABC"
            };

            yield return cust;
        }
    }
}

Controller

public ActionResult V1()
    {            
        return View(Customer.GetCustomers());
    }

    public ActionResult V2()
    {
        return View(Customer.GetCustomers());
    }

V1 (which has performance issue)

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Customer>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    V1
</asp:Content>

<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">

    <h2>V1</h2>
    <table>
    <%foreach (var cust in this.Model)
      {%>
        <%= Html.DisplayFor(m => cust) %>  
      <%} %>
    </table>
</asp:Content>

And Template is

<%@ Control Language="C#" Inherits="System.Web.Mvc.ViewUserControl<Customer>" %>
<tr>
    <td><%= this.Model.CustomerId %></td>
    <td><%= this.Model.Name %></td>
    <td><%= this.Model.Address %></td>
    <td><%= this.Model.EmailAddress %></td>    
</tr>

V2 (no performance issue)

<%@ Page Title="" Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<IEnumerable<Customer>>" %>

<asp:Content ID="Content1" ContentPlaceHolderID="TitleContent" runat="server">
    V2
</asp:Content>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <h2>V2</h2>
    <table>
    <%foreach (var cust in this.Model)
      {%>
        <tr>
            <td><%= cust.CustomerId%></td>
            <td><%= cust.Name%></td>
            <td><%= cust.Address%></td>
            <td><%= cust.EmailAddress%></td>    
        </tr>
      <%} %>
      </table>
</asp:Content>

I can easy see the performance difference between V1 and V2.

EDIT: When I deploy to my local IIS 7 (with Release version) and it (V1) becomes very fast. The issue is solved, but I still want to know the reason. :)

Thanks,
Soe Moe

A: 

The issue is that DisplayFor() uses a lambda expression which is compiled and executed at runtime.

Therefore, the performance difference in V1 can be attributed to this "intermediate" compilation step.

V2 is simply a property access which does not need any compilation.

I'm taking a guess here, but I imagine that IIS7 is smart enough to keep a cached copy of the view (and the compiled lambda expressions) around for future re-use, meaning subsequent render times will be comparable to V1 in IIS 6.

Codebrain
The assumption that IIS7 is the key factor here, is not correct. See Levi's answer for the correct information.
Thomas J
IIS7 was mentioned after the answer was accepted so I cannot delete it :(
Codebrain
+9  A: 

Caching is enabled only in release mode. If you run the application in debug mode, you might see a performance hit due to disk accesses.

See also: http://codeclimber.net.nz/archive/2009/04/22/how-to-improve-htmlhelper.renderpartial-performances-donrsquot-run-in-debug-mode.aspx

Levi
Thanks! I switched debug to false and the performance went back to what I expected it to...
J.13.L