Alik Levin's

Clarity, Technology, and Solving Problems | 

July, 2008

  • Alik Levin's

    Best ASP.NET Performance Winner For Data Binding - Hands Up To Response.Write()


    Alik Levin     To achieve best performance you need to make decisions based on trade-off between coolness, coding productivity, and personal engineering values. I never thought I would be recommending my customer considering using old fashion Response.Write() in his Internet facing ASP.NET web application in order to significantly improve the application’s performance.

    Customer Case Study

    During load/stress testing customer’s ASP.NET web application we identified high CPU utilization (up to 90%). After quick investigation we noticed that %Time in GC performance counter is less than optimal. Our assumption was that the application uses memory allocation techniques that are less than optimal. From GC Performance Counters:

    "First thing you may want to look at is “% Time in GC”... What is a health value for this counter? It’s hard to say. It depends on what your app does. But if you are seeing a really high value (like 50% or more) then it’s a reasonable time to look at what’s going on inside of the managed heap."

    Another resource we used is timeless patterns & practices’ Chapter 15 — Measuring .NET Application Performance:

    .NET CLR Memory\% Time in GC

    "…The most common cause of a high value is making too many allocations, which may be the case if you are allocating on a per-request basis for ASP.NET applications. You need to study the allocation profile for your application if this counter shows a higher value."

    So we headed to looking into the code and this is what we found out.


    During performance code inspection we identified massive usage of collections. The collections were used to transfer the data between the logical layers and then the collections were transferred into datatables to be bindable for DataGrid (yes, it is .Net 1.1 app).

    Eureka! We just spotted 3 performance anti-patterns. Massive memory allocation, massive loops, massive type conversions. I’ve shown it to 4 very respected professionals and everyone was saying the same – current situation is pure performance anti-pattern. Here are few suggestions that came up:

    • Bind collections directly to DataGrid eliminating additional memory allocations and loops.
    • Create Datatable directly from XML skipping collection creation step eliminating additional memory allocations and loops.
    • Use Xslt transformation transforming original Xml into Html table using Xslt elminating memory allocations and loops for both collections and datatables.
    • Use Response.Write() as it’s suggested by patterns & practices:

    "Use the Response.Write method. It is one of the fastest ways to return output back to the browser."

    Case close? Not really...

    Secretly I’ve built Visual Studio 2003 project with these implementations and ran simple stress test using TinyGet utility. The results left us all a bit surprised.

    Converting Collection To Datatable (Current Situation)

    The code:

       1: //create custom collection
       2: MyCollection myCollection = (MyCollection)SampleServices.GenerateCollection(200);
       4: //convert collection to datatable
       5: DataTable datatable = SampleServices.ConvertCollectionTableIntoDataTalbe(myCollection);
       7: //bind datatalbe to dynamically created datagrid
       8: datagrid.DataSource = datatable;
       9: datagrid.DataBind();
    The stress test:
    tinyget.exe  -srv: -uri:/dynamiccontrolsloadingrelease/UseDataTable.aspx -loop:100 -threads:15
    The result:

    Bind Collection Directly To Grid

    The code:

       1: MyCollection myCollection = (MyCollection)SampleServices.GenerateCollection(200);
       3: //bind datatalbe to dynamically created datagrid
       4: datagrid.DataSource = myCollection;
       5: datagrid.DataBind();

    The stress test:

    tinyget.exe  -srv: -uri:/dynamiccontrolsloadingrelease/UseCustomCollection.aspx -loop:100 -threads:15

    The result:



    Create Datatable From Xml

    The code:

       1: string xml = SampleServices.GenerateXml(200);
       3: StringReader theReader = new StringReader(xml);
       4: DataSet theDataSet = new DataSet();
       5: theDataSet.ReadXml(theReader);
       7: datagrid.DataSource = theDataSet.Tables[0].DefaultView;;
       8: datagrid.DataBind();

    The stress test:

    tinyget.exe  -srv: -uri:/dynamiccontrolsloadingrelease/LoadXmlIntoDataTable.aspx -loop:100 -threads:15

    The result:


    Use Xslt Transformation To Create Html Table

    The code:

       1: Xml1.DocumentContent = SampleServices.GenerateXml(200);
       2: Xml1.TransformSource=@"xsl.xml";

    The stress test:

    tinyget.exe  -srv: -uri:/dynamiccontrolsloadingrelease/XmlXslTransformation.aspx -loop:100 -threads:15

    The result:


    Use Response.Write()

    The code:

       1: MyCollection myCollection = (MyCollection)SampleServices.GenerateCollection(200);
       3: // Put user code to initialize the page here
       4: Response.Write("<table>");
       6: foreach(MyModelItem item in  myCollection)
       7: {
       9:     Response.Write("<tr>");
      10:     Response.Write("<td>" +  item.Address  + "<td>");
      11:     Response.Write("<td>" +  item.City  + "<td>");
      12:     Response.Write("<td>" +  item.Education+ "<td>");
      13:     Response.Write("<td>" +  item.Family  + "<td>");
      14:     Response.Write("<td>" +  item.Name  + "<td>");
      15:     Response.Write("</tr>");
      16: }
      17: Response.Write("</table>");

    The stress test:

    tinyget.exe  -srv: -uri:/dynamiccontrolsloadingrelease/ResponseWrite.aspx -loop:100 -threads:15

    The result:


    Sample Visual Studio 2003 Project

    Interested in testing it yourself? Grab the source code from my SkyDrive here:


    After conducting this simple test these are the conclusions I’ve made:

    • “Don't be afraid to challenge the pros, even in their own backyard." - How to Get Things Done - Colin Powell Version
    • Testing IS DA thing. Assumptions are good but nothing speaks louder than facts.
    • Test early - avoid massive rework afterwards. Create POC's (Proof of concept) early in architecture/design stages.
    • Best performance comes on expense of productivity and coolness.

    Related Materials

  • Alik Levin's

    Security Code Review – String Search Patterns For Authorization Vulnerabilities


    These are the questions and the search criteria I use to identify authorization vulnerabilities in the code beyond web.config <authorization> node.

    • How does the code protect access to page classes?


    Search for PrincipalPermission attributes. If there is no match, the code does not perform standard authorization checks.

    findstr /S /I "PrincipalPermission" *.cs

    Empirical checks

    Search for empirical IsInRole calls. If there is no match, the code does not perform standard authorization checks.

    findstr /S /I "IsInRole" *.cs


    Search for empirical IsUserInRole calls for Rolemanager API. If there is no match, the code does not perform standard authorization checks.

    findstr /S /I "IsUserInRole" *.cs

    • Does the code use Server.Transfer?

    When the code uses Server.Transfer it may improve performance but potentially it may pose a threat of elevation of privileges, more info is here Performance Gain - Security Risk

    findstr /S /I "Transfer" *.cs

    Related posts

  • Alik Levin's

    Performance Improvements In Architecture (Hebrew) – My Guest Post On MCS Israel Blog


    Just posted guest post on MCS (Microsoft Consulting Services) Israel blog about performance in architecture and related case study.

    MCS Israel blog is a mixture of English and Hebrew posts from Microsoft Israel architects and consultants.

    Do you read in Hebrew?

    Enjoy - סיפור לקוח – שיפור ביצועים מערכת מידע ברמת ארכיטקטורה

Page 1 of 3 (7 items) 123