日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

各种URL生成方式的性能对比

發布時間:2023/11/29 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 各种URL生成方式的性能对比 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

在上一篇文章中我們列舉了各種URL生成的方式,其中大致可以分為三類:

  • 直接拼接字符串(方法一及方法二)
  • 使用Route規則生成URL(方法三)
  • 使用Lambda表達式生成URL(方法四及方法五)
  • 我們可以輕易得知,這3種作法可維護性依次增加,而性能依次減少。不過,我們還是有一個疑問,這個性能究竟相差多少?它是否的確真的可以被忽略?為此,我們還是來進行一次性能對比吧。

    測試對象

    為了獲得貼近實際的測試結果,我打算以我的博客首頁作為測試對象。您可以發現,這個頁面上的鏈接非常多,我把它分為三個部分:

  • 文章(Post)列表:主體部分的40篇文章,其中每篇文章包含1個詳細頁鏈接以及5個Tag。
  • 邊欄文章列表:假設邊欄列舉了120篇文章的鏈接。
  • 歸檔(Archive)列表:也就是每個月的文章鏈接,3年共36個鏈接。
  • 作為一個演示,我也精心準備了四種URL模式,它們分別是:

    // 博客首頁 routes.MapRoute("Blog.Index","{blog}",new { controller = "Blog", action = "Index" });// 標簽頁 routes.MapRoute("Blog.Tag","{blog}/tag/{tag}",new { controller = "Blog", action = "Tag" });// 按月歸檔頁 routes.MapRoute("Blog.Archive","{blog}/archive/{year}/{month}.html",new { controller = "Blog", action = "Archive" });// 文章詳細頁 routes.MapRoute("Blog.Post","{blog}/archive/{*post}",new { controller = "Blog", action = "Post" });

    以上代碼在Web項目中的GlobalApplication.cs文件中。您可以發現,我完全按照博客園在定制URL的模式。我想說明的是,其實URL Routing完全非常靈活,您可以根據需求使用各種形式的URL,關鍵只是“規則配置”而已。不過雖然配置了4種Route規則,但是我只實現了BlogController下的一個Action:博客首頁(Index),如下:

    [RouteName("Blog.Index")] public ActionResult Index([ModelBinder(typeof(BlogBinder))]Blog blog, string view) {var model = new IndexModel { Blog = blog, Posts = GetPosts() };return View("Index" + view, model); }private static List<Post> GetPosts() {... }[RouteName("Blog.Post")] public ActionResult Post([ModelBinder(typeof(BlogBinder))]Blog blog,[ModelBinder(typeof(PostBinder))]Post post) {throw new NotImplementedException(); }[RouteName("Blog.Tag")] public ActionResult Tag([ModelBinder(typeof(BlogBinder))]Blog blog,[ModelBinder(typeof(StringBinder))]string tag) {throw new NotImplementedException(); }[RouteName("Blog.Archive")] public ActionResult Archive([ModelBinder(typeof(BlogBinder))]Blog blog,int year,int month) {throw new NotImplementedException(); }

    BlogController.cs文件處于Web.Controllers項目中。我為每個復雜參數都安排了ModelBinder,具體實現都很簡單,您可以下載文末的代碼進行瀏覽。在GetPosts里我將準備40個Post對象,每個Post對象分配5個Tag,這些都將顯示在頁面上。Index方法的參數view通過Query String進行傳遞,例如,您可以通過一下三個鏈接來訪問不同的URL生成方式:

    • /jeffz?view=ByRaw:使用拼接字符串的方式生成URL
    • /jeffz?view=ByRoute:使用Route規則生成URL
    • /jeffz:使用Lambda表達式這個“推薦方式”生成URL

    三種方式

    在Web.UI項目中的Views目錄下有BlogController所使用的三個視圖模板,他們使用不同的方式來生成完全一樣的內容。例如Index.aspx文件中的定義是這樣的:

    <!-- 主體文章列表,40篇,各5個Tag --> <h2>Posts</h2> <ul><% foreach (var post in Model.Posts) { %> <li>Title: <a href="<%= Url.ToPost(Model.Blog, post) %>"><%= Html.Encode(post.Title) %></a>Tag: <% foreach (var tag in post.Tags) { %> <a href="<%= Url.ToTag(Model.Blog, tag) %>"><%= Html.Encode(tag) %></a> | <% } %> </li><% } %> </ul><!-- 邊欄文章列表,共計120篇 --> <h2>More post links</h2> <ul><% for (int i = 0; i < 3; i++) { %> <% foreach (var post in Model.Posts) { %> <li style="display: inline;"><a href="<%= Url.ToPost(Model.Blog, post) %>"><%= Html.Encode(post.Title) %></a> |</li><% } %> <% } %> </ul><!-- 歸檔列表,3年共計36個鏈接 --> <h2>Archives</h2> <ul><% for (int year = 2007; year <= 2009; year++) { %> <% for (int month = 1; month <= 12; month++) { %> <li><a href="<%= Url.ToArchive(Model.Blog, year, month) %>"><%= year %><%= month %></a></li><% } %> <% } %> </ul>

    對于IndexByRaw.aspxIndexByRoute.aspx來說,它們只是把ToPost,ToTag等方法改為對應的ToPostByRaw或ToTagByRoute而已。因此,其實生成URL的關鍵還在于這些輔助方法。例如ToPost,ToTag和ToArchive三個擴展方法是這樣實現的:

    public static string ToPost(this UrlHelper helper, Blog blog, Post post) {return helper.Action<BlogController>(c => c.Post(blog, post)); }public static string ToTag(this UrlHelper helper, Blog blog, string tag) {return helper.Action<BlogController>(c => c.Tag(blog, tag)); }public static string ToArchive(this UrlHelper helper, Blog blog, int year, int month) {return helper.Action<BlogController>(c => c.Archive(blog, year, month)); }

    可見,使用Lambda表達式構造URL的代碼非常清晰,簡單,直觀——因為Action輔助方法會自動從Lambda表達式中提取Controller和Action名,并調用每個參數的RouteBinder實現復雜類型參數的雙向轉化,它不需要我們關心更多的東西。

    而如果直接拼接字符串,那么它可能就是這樣的:

    public static string ToTagByRaw(this UrlHelper helper, Blog blog, string tag) {return blog.Alias + "/tag/" + HttpUtility.UrlEncode(tag); }

    而基于Route構造URL就會顯得略麻煩一些:

    public static string ToTagByRoute(this UrlHelper helper, Blog blog, string tag) {var path = helper.RouteCollection.GetVirtualPathEx(helper.RequestContext,"Blog.Tag",new RouteValueDictionary{{ "controller", "Blog" },{ "action", "Tag" },{ "blog", blog.Alias },{ "tag", HttpUtility.UrlEncode(tag) }});return path.VirtualPath; }

    至于后兩種方式的其它幾個輔助方法,您可以下載文末的代碼進行瀏覽,它們都在Web.Controllers項目中的UrlGenExtensions.cs文件中。

    運行測試

    我們使用BlogController中另一個Action方法:Benchmark進行性能測試。Benchmark方法接受兩個參數,一個是循環次數,而另一個則是測試目標:

    public ActionResult Benchmark(int iteration, string view) {var model = new IndexModel{Blog = new Blog { Alias = "jeffz" },Posts = GetPosts()};var result = new BenchmarkModel{Iteration = iteration,View = "Index" + view};var viewInstance = new WebFormView("~/Views/Blog/Index" + view + ".aspx");var viewContext = new ViewContext(this.ControllerContext,viewInstance,new ViewDataDictionary(model),new TempDataDictionary());// warm upviewInstance.Render(viewContext, new StringWriter());GC.Collect();var watch = new Stopwatch();watch.Start();for (int i = 1; i <= iteration; i++){viewInstance.Render(viewContext, new StringWriter());if (i % 100 == 0){result.Add(i, watch.Elapsed);}}watch.Stop();return View(result); }

    于是,您可以使用下面的鏈接觀察使用三種方法生成1000次頁面所消耗的時間:

    • /benchmark?iteration=1000&view=ByRaw:使用拼接字符串的方式生成URL
    • /benchmark?iteration=1000&view=ByRoute:使用Route生成URL
    • /benchmark?iteration=1000:使用Lambda表達式生成URL

    Benchmark方法會每隔100次記錄一下結果,因此上面的鏈接加載完后會出現10條信息——這便是我們得到的結果。

    結果

    至于最終的結果以及分析,我打算暫時賣個關子,不多久我就會獨立開篇進行說明的。您可以在這里下載到整個解決方案,代碼不多,但也花費了我2個小時進行準備,您可以親自試驗一下。您直接使用上面的Benchmark鏈接進行觀察即可,生成1000次頁面已經足以展示一些問題了——不過在此之前,您不妨進行一個預測,猜猜看它們之間究竟有多大的性能差距。

    相關文章

    • 各種URL生成方式的性能對比
    • 各種URL生成方式的性能對比(結論及分析)
    • 為URL生成設計流暢接口(Fluent Interface)
    • URL生成方式性能優化結果
    • Route組件GetVirtualPath方法性能優化結果

    總結

    以上是生活随笔為你收集整理的各种URL生成方式的性能对比的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。