ASP.NET MVC URL generation performance

半世苍凉 提交于 2019-12-02 20:47:54

I asked this question on the MS forums, which got an answer from an MS MVC developer.

The post

The answer

From MVC Preview 2 to the recently released MVC Beta from yesterday there have been a lot of changes to Routing. Some of those changes include performance improvements. Here are some tricks to make URL generation more performant in your application:

  1. Use named routes. Named routes are an optional feature of routing. The names only apply to URL generation - they are never used for matching incoming URLs. When you specify a name when generating a URL we will only try to match that one route. This means that even if the named route you specified is the 100th route in the route table we'll jump straight to it and try to match.

  2. Put your most common routes at the beginning of the route table. This will improve performance of both URL generation as well as processing incoming URLs. Routing works based on the rule that the first match wins. If the first match is the 100th route in your route table, then that means it had to try 99 other routes and none of them matched.

  3. Don't use URL generation. Some people like it, some people don't. It's a bit tricky to master. It's nice to use if your URLs are very dynamic but it can be a bit of a hassle when you have very few URLs to begin with and perhaps you don't care about exactly what they look like.

My favorite option is #1 since it's super easy to use and it also makes URL generation more deterministic from the app developer's perspective (that's you!).

Caching links would probably be a good suggestion for the team, as they won't change for the life of the process (for most apps anyway).

Until you start defining your routes in a configurable form (such as web.config or in a database) then you'd have to scale back a bit.

I suspect that a big portion of the delay on the middle example is the anonymous type that gets automatically converted to a dictionary. Caching the URL wouldn't help here b/c you'd still need to reflect that type.

In the meantime, you can create your own helper methods for some of those dictionary-based links that take the exact input you require. Then you can handle the caching yourself.

Ok, two additional metrics on the blank template project:

<%= Bechmark(() => Url.Action("Login", "Account", new Dictionary<string, object> {{"username", "bla"}, {"password", "bla2"}, {"returnurl", "blabla32"}, {"rememberme", "false"}})) %>

<%= Bechmark(() => Url.Action("Login", "Account", new RouteValueDictionary(new Dictionary<string, object> {{"username", "bla"}, {"password", "bla2"}, {"returnurl", "blabla32"}, {"rememberme", "false"}}))) %>

Results:

71 ms, 0,071 ms per link

35 ms, 0,035 ms per link

Much better performance with way nastier code. Too bad.

Caching links would probably be a good suggestion for the team, as they won't change for the life of the process (for most apps anyway).

How can you cache links, you can't do that as far as I know, because you need to cache the method that gets executed, which happens after the route gets resolved, which is the slow part.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!