Opinionated Input Builders Part 6 – Performance of the builders

Update – 6/14/2009 Chad Myers blogged about the trade offs and the importance of productivity over premature optimizations.

Update 6 /14/2009 Please see the second set of tests I ran for a large performance increase.


Multiple people asked about the performance implications of using this style of input builders.  First let me say that as far as performance, using the partial views is probably the least efficient way to render html.  But with every approach there are tradeoffs. In this case we are trading run time performance for developer productivity and codebase and user interface consistency. That being said I cannot answer what the best approach is for you. That depends on the size of your team , the size of your project, the skill set of your team and a number of other aspects which determine what the best approach is.  For instance I would not use input builders or a MVC view if I was building a form to collect votes for American Idol.  I would actually create the forms in static html pages.  The scalability would require the best performing solution.



The Control Test

With any good test you have to have a control case. In this case I ran a load test against an empty MVC view that was using the same Master Page as my form page.  I ran a constant load against that page in IIS 7, on a x64 Vista OS for 10 minutes.  The results is that I have a maximum Request / Second of 1,622 and an Average Requests / Second of 1,275. You can see the chart below of the Requests/Second.


The Load Test

Next I ran the same test against the page I have used for all of the samples in this series.  With the same load , machine configuration, and duration as the control test.  In this case my Maximum Requests/Second was 442 and the Average Requests/Second were 351.  What does that mean?  I lost 75% of my page request through put by using the Input Builders. Does this mean we should not use the input builders?  The answer is … it depends.  What through put do you need? From my experience I have found that most forms backed by a data store cannot scale to 400 Requets / Sec without some significant architectural principles in play.  Such as asynchronous messaging and other methods to scale. 



What are the next steps for performance?

The next step for me is running the load test with a Profiler attached to the process.  I used the JetBrains Dot Trace application.  It is nice because after I run the profile session and analyze the data it has a quick and dirty Hot Spot report.  This show the single biggest offender of my codebase.  This means that if I optimize the code below that will have the biggest improvement for performance.  It is a combination of the time it takes to execute this code combined with the number of times this code path is executed.  That being said, lets dig into it. 

The 3rd call in this stack is part of the RenderPartial call I do not totally understand the internals of the MVC view engine and I will not pretend to. If I really wanted to see more it would make sense to pull down the MVC source code and build it with is symbol files, than the profiler could give me more information.  So what I am surprised by is that my hunch when first thinking about performance would have taken me to the reflection and Lamda Expression code, but this test shows that the biggest bottle neck is in the control / partial rendering.  So by using this tool I have saved myself a huge headache by preventing myself from optimizing the wrong code.  At this point I am going to put this information together and get it in front of those in the .Net Community who are way smarter than I am and of course, get it to the brainiacs at Microsoft who wrote this stuff to suggest some approaches for better performance . They know their internal benchmarks as well as what they are planning for the future. 

The biggest lesson I can demonstrate here is do not pre optimize.  I already wasted 20 minutes of my time and Jimmy Bogard’s time talking about different ways to optimize Lambda Expressions.  It is clear that implementing those optimizations would not make a single difference in effecting the output of this performance test.



Should you use the builders?

Well that decision is really up to you, but I hoped that I demonstrated a scientific approach to answering that question. For me the componentization of the HTML and the productivity increases of using the builders far outweigh the runtime performance issues.  Again, I would take this on a case by case basis and when I need more throughput than what I can provide with this approach I would consider a different method of mark up generation.

About Eric Hexter

I am the CTO for QuarterSpot. I (co)Founded MvcContrib, Should, Solution Factory, and Pstrami open source projects. I have co-authored MVC 2 in Action, MVC3 in Action, and MVC 4 in Action. I co-founded online events like mvcConf, aspConf, and Community for MVC. I am also a Microsoft MVP in ASP.Net.
This entry was posted in .Net, Asp.Net, Asp.Net MVC, c#, CoC, mvccontrib. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • smurf

    thx for that post, i already assumed that the performance will suffer from a lot RenderPartial calls, but with this post it is proofed.

    in the CodeCampServer project the InputBuilder approach just build strings, without using partials.

    so i would really like it, if you would provide an option to switch between partials and string building and retest the performance with it. (i’m very interested in the results). so people can choose the option which fits best for their needs.

    when do you guesstimate to have a first version one can use? (i already extracted the inputbuilders of codecampserver for the next project ;) )

  • @smurf I do not plan on building a string based version because it has caused me pain trying to reuse it from project to project. I think we could consider it in the future or once this gets into mvccontrib see if someone in the community would be willing to achive the same results with a string based approach.

    I will run the test against a page build using the string version of the builders and we can see what its performance footprint looks like.
    I think I have a few more posts to get some feedback on the way that the partials are named before I commit this to mvccontrib. Not too much longer….

  • Eric, did you make sure to do your perf runs NOT in debug mode? When in debug mode, some optimizations in the view engine are turned off, such as caching.

  • smurf

    eric, take your time.

    What was the pain in reusing?

    if you don’t provide a string based version, please mind DI to plug it in via a container easely

  • @Haacked, I did set debug=false in the config. But I am using a virtualPathProvider to read partials out of my assembly. So I think it would be good to pull that out and see what the performance looks like. I know there is caching provided by the path provider that is not being handled by my implementation.

    @Chad totally agree that the performance issues are solvable and in most cases perform good enough for most projects. The other reason I would suggest sticking with this approach is that as I get this into MvcContrib, we will be optimizing this and as a result solving problems for the community so that as a community we can solve this and provide more efficiency/productivity. I hope we can do this through runtime enhancements rather than through precompilation but if that is what it takes … that is an option.

  • @smurf, There will be a way to extend this and plugin your own DI. I prefer to expose that through some sort of factory method so that this framework does not take a direct dependency on a DI framework and force that on everyone else.. I hate when Open Source Projects do that.

  • smurf

    the same is true for me

  • I’m running this on my local machine with debug enabled and seeing a 400ms duration between just the controller and view rendering.

    Thats pretty unacceptable to just render a form.