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)

Earlier today I wrote a post about how to improve the performance of ASP.NET MVC web applications, and I came out with the conclusion that the best way to improve performance is to add data caching and that the rest was not very important.

Rudi sent me an email pointing out that turning the optimization upside down as I asked in my post, the expression tree-based ActionLink method still causes a lot of performance problems, at least in his sample application, a DIGG-like application, where there are 4 calls to the ActionLink helper for each of the 20 items displayed on the page plus some other calls around the page (from a slide of the presentation, it seems like the sample calls the method at least 160 times per page).

So I decided to analyze the results of his performance test better, and it really turns out that, in his context, with hundreds of calls to the ActionLink method, this method is a big performance issue.

Go and have a look at the original presentation, on page 26, to read the reasons why it is so slow.

What are the data really saying?

I based my previous assumptions on the number of requests per second gained, but I missed one important factor: relative gain. Gaining 10 requests with a baseline of 6 is a much better improvement than gaining 25 on a baseline of 60.

So I created that graphs that help visualize the real relative gain:

PercentualGain

The best relative improvement still happens with data caching (a 427% gain), but the second one (150% gain) is using the RouteLink helper specifying the RouteName instead of the lambda expression-based ActionLink helper. The third one is again something related to data (using compiled LINQ queries, with a 94% gain) and then another ASP.NET MVC related issue: specifying the full path to a view is 63% faster (in his scenario where partial views are called 41 times per view) then specifying the view name only. 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.

UPDATE: Rudi tested everything with the beta version, and since then the WebFormViewEngine caches the resolution of view paths. Furthermore also running in debug mode disables the caching. So this is not a performance issue. Read more about this on my follow-up post: Stopping the panic: how to improve HtmlHelper.RenderPartial performances. Don’t run in debug mode

Analyzing one of the other two graphs would have lead to the wrong conclusion: the req/sec was emphasizing the gain provided by the data caching too much, and the time per request emphasizes too much the gain caused by not using the expression tree based method:

ReqPerSecGain TimePerRequestGain

What do we get from this?

Number 1 - a correct data visualization is the key to understanding the problems better.

Number 2 – Data caching is still the most effective way to improve the performance of a data driven application.

Number 3 - the expression tree based ActionLink helper has some performance problems.

Number 4 - if the test was performed on the RTM, there is a bug in the caching of view path resolution.

What can you do to to help your performance?

Implementing a route resolution cache, might boost the performance of all the url generation story, and I think that this is something Microsoft should look at for a next version of the routing engine.

posted on Friday, April 17, 2009 8:06 PM

Comments on this entry:

# re: The performance implications of the expression tree-based ActionLink helper

Left by Sergejus at 4/17/2009 11:46 PM

Simone, what have you used for the benchmarking? Apache Benchmark? If so, do you know is it any way to use it for the ASP.NET WebForms benchmarking?

# re: The performance implications of the expression tree-based ActionLink helper

Left by Simone at 4/17/2009 11:56 PM

Hi Sergejus,
I didn't run the tests....
the test were run by Rudi (read the presentation where he explains how he did everything www.slideshare.net/.../aspnet-mvc-performance ), and yes, he did used Apache Benchmark.
AFAIK, Apache Benchmark is just a stress test tool: just point it to your page, an launch it.
ab -n 1000 -c 1 http://yousite.com

# re: The performance implications of the expression tree-based ActionLink helper

Left by Sergejus at 4/18/2009 11:13 AM

OK, I've read this really nice presentation, but I thought you re-run the tests. Seems there is a need to take a close look on Apache Benchmark...

# re: The performance implications of the expression tree-based ActionLink helper

Left by Simone at 4/18/2009 12:40 PM

No, I didn't... the code was not available. Now I think I'd re-run something to verify the view path resolution problem.

If you have VisualStudio, you can use the load test test, which does the same things... and it's even better :)

Comments have been closed on this topic.