av激情亚洲男人的天堂国语,日韩欧美精品一中文字幕,无码av一区二区三区无码,国产又色又爽又刺激的a片,国产又色又爽又刺激的a片

ASP.NET頁面優(yōu)化:性能提升8倍的方法

閱讀目錄

創(chuàng)新互聯(lián)公司服務項目包括崇陽網(wǎng)站建設、崇陽網(wǎng)站制作、崇陽網(wǎng)頁制作以及崇陽網(wǎng)絡營銷策劃等。多年來,我們專注于互聯(lián)網(wǎng)行業(yè),利用自身積累的技術優(yōu)勢、行業(yè)經(jīng)驗、深度合作伙伴關系等,向廣大中小型企業(yè)、政府機構(gòu)等提供互聯(lián)網(wǎng)行業(yè)的解決方案,崇陽網(wǎng)站推廣取得了明顯的社會效益與經(jīng)濟效益。目前,我們服務的客戶以成都為中心已經(jīng)輻射到崇陽省份的部分城市,未來相信會繼續(xù)擴大服務區(qū)域并繼續(xù)獲得客戶的支持與信任!


  1. 開始
  2. 測試背景
  3. 測試方法
  4. 測試用例1:WebFromPage.aspx
  5. 測試用例2:InlinePage.aspx
  6. 分析優(yōu)化結(jié)果1
  7. 測試用例3:InlineUserControl.ascx
  8. 分析優(yōu)化結(jié)果2

今天與大家分享:一種優(yōu)化頁面執(zhí)行速度的方法。

采用這個方法,可以使用頁面的執(zhí)行速度獲得【8倍】的提升效果。

為了讓您對優(yōu)化的效果有個直觀的了解,我準備了下面的測試結(jié)果截圖:

測試環(huán)境:

  1. Windows Server 2003 SP2
  2. Viaual Studio 2008,使用自帶的WebDev.WebServer.EXE運行網(wǎng)站程序。
  3. (ThinkPad SL510):Core2 T6670 2.2GHz, 4G內(nèi)存

二個紅框中的數(shù)字反映了優(yōu)化前后的執(zhí)行時間。

數(shù)字表明:優(yōu)化前后,執(zhí)行時間有了8倍多的差別。

本文的測試結(jié)果也僅僅只是一個參考數(shù)字,這個結(jié)果也只是根據(jù)我所設計的測試頁面得出的。

優(yōu)化的過程中,如果不使用服務器控件,那么給GC減少的壓力其實也是無法測試到的。

在測試過程中,我還發(fā)現(xiàn)測試結(jié)果并不是很穩(wěn)定,因此截圖具有一定的偶然性。

測試頁面或許在某些方面存在一些片面性,因此,結(jié)果僅供參考。

測試背景

看過了優(yōu)化結(jié)果,再來介紹一下:這個測試到底是在測試什么東西?

現(xiàn)在有很多做ASP.NET的開發(fā)人員,應該都是從ASP.NET的WebForm編程模型開始學習的。大家都很喜歡用服務器控件,不管輸出什么,都會使用服務器控件。有時候為了讓頁面呈現(xiàn)干凈的HTML代碼,有些人會選擇使用Repeater,Literal這類簡單的服務器控件?;蛟S有些人認為:我已不使用GridView這樣強大復雜的控件,頁面執(zhí)行速度已經(jīng)很快了。

真是這樣嗎?

今天測試的起點就從使用簡單的服務器開始,我會分二次對它做一系列的性能優(yōu)化。

最終就是上圖中的3個結(jié)果,它們反映了二次優(yōu)化的改進過程。

在繼續(xù)介紹之前,有一點我想有必要說明一下:

優(yōu)化的過程涉及到ASP.NET服務器控件的使用,測試結(jié)果也僅僅只是一個參考數(shù)字。

如果您認為您的開發(fā)工作非常依賴于服務器控件的使用,

那么測試結(jié)果對您來說其實是無意義的,請不要在意這個結(jié)果。

測試方法

在這次優(yōu)化過程中,我并沒有設計很復雜的測試頁面,而是一個很簡單的測試頁面,頁面顯示效果如下:

這個頁面其實就是顯示了一堆超鏈接,它們來自于我的博客側(cè)邊欄的【推薦排行榜】,總共有20條記錄,我讓頁面重復5次輸出,也就是生成了100個超鏈接。

測試的數(shù)據(jù)是這樣獲取的:

我復制了我的博客側(cè)邊欄的【推薦排行榜】的那段HTML代碼,保存到一個文件中:

然后,網(wǎng)站在初始化時,從這段HTML代碼提取鏈接地址以及顯示文字,保存到一個BlogInfo的列表中,代碼如下:

 
 
 
 
  1. public class BlogInfo  
  2. {  
  3.     public string Title;  
  4.     public string Href;  
  5. }  
  6.  
  7. public static class XmlDb  
  8. {  
  9.     public static List Blogs { get; private set; }  
  10.  
  11.  
  12.     public static void LoadBlogs()  
  13.     {  
  14.         string filePath = Path.Combine(HttpRuntime.AppDomainAppPath, @"App_Data\RecommendList.html");  
  15.  
  16.         XElement html = XElement.Parse(System.IO.File.ReadAllText(filePath));  
  17.  
  18.         Blogs =  
  19.             (from a in html.Elements("li").Elements("a")  
  20.              select new BlogInfo { Title = a.Value, Href = a.Attribute("href").Value }).ToList();  
  21.     }  

測試時,就把XmlDb.Blogs的內(nèi)容顯示在網(wǎng)頁中。
我想這個測試還是比較接近于現(xiàn)實開發(fā)的。

這里又有一個問題:我如何測試頁面的執(zhí)行速度?

雖然說創(chuàng)建HttpWebRequest訪問頁面是個很簡單的方法,但我并不打算這樣做。
因為從HttpWebRequest發(fā)起調(diào)用到獲取結(jié)果,這其中除了有頁面的執(zhí)行時間,還混雜較多的額外調(diào)用開銷。最終,我選擇了在一次HTTP請求中,循環(huán)調(diào)用Server.Execute來執(zhí)行頁面,并統(tǒng)計時間的方式。其實如何選擇測試方法,對于二個測試對象還說,都是公平的。只是說:盡量減少一些額外的調(diào)用開銷,會讓測試結(jié)果的差異更大,也更明顯。

說明:為了測試代碼寫起來簡單,我使用了MyMVC框架。

測試用例1:WebFromPage.aspx

前面介紹了測試背景以及測試方法。現(xiàn)在就來介紹第1個測試用例,它采用了WebForm編程模型中最經(jīng)典的寫法。

頁面代碼:

 
 
 
 
  1. <%@ Page Language="C#" CodeFile="WebFromPage.aspx.cs" Inherits="TestPage_WebFromPage" %> 
  2.  
  3.  
  4.  
  5.     PagePerformanceTest   http://www.cnblogs.com/fish-li/ 
  6.  
  7.  
  8.  
  9. This is WebFromPage.aspx

     
  10.  
  11.  
  12.  
  13.      
  14.  
  15.  
  16.  
  17.  
  18.  
  19.  
  20.      
  21.  
  22.  
  23.  
  24.  
  25.  
  26.  
  27.      
  28.  
  29.  
  30.  
  31.  
  32.  
  33.  
  34.      
  35.  
  36.  
  37.  
  38.  
  39.  
  40.  
  41.      
  42.  
  43.  
  44.  
  45.  
  46.  
  47.  
  48.  

頁面的CodeFile代碼:

 
 
 
 
  1. public partial class TestPage_WebFromPage : System.Web.UI.Page  
  2. {  
  3.     protected override void OnLoad(EventArgs e)  
  4.     {  
  5.         base.OnLoad(e);  
  6.  
  7.         repeater1.DataSource = XmlDb.Blogs;  
  8.         repeater1.DataBind();  
  9.         repeater2.DataSource = XmlDb.Blogs;  
  10.         repeater2.DataBind();  
  11.         repeater3.DataSource = XmlDb.Blogs;  
  12.         repeater3.DataBind();  
  13.         repeater4.DataSource = XmlDb.Blogs;  
  14.         repeater4.DataBind();  
  15.         repeater5.DataSource = XmlDb.Blogs;  
  16.         repeater5.DataBind();  
  17.     }  
  18.  
  19.     protected void repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)  
  20.     {  
  21.         if( e.Item.ItemType == ListItemType.Item ) {  
  22.             BlogInfo blog = e.Item.DataItem as BlogInfo;  
  23.             HyperLink link1 = e.Item.FindControl("link1") as HyperLink;  
  24.             link1.NavigateUrl = blog.Href;  
  25.             link1.Text = blog.Title;  
  26.         }  
  27.     }  

測試代碼:

 
 
 
 
  1. [Action]  
  2. public object Test1(string callTimes)  
  3. {  
  4.     int count = 0;  
  5.     int.TryParse(callTimes, out count);  
  6.     if( count <= 0 )  
  7.         return count;  
  8.  
  9.     HttpContext context = HttpContext.Current;  
  10.       
  11.     // 先執(zhí)行一次,排除編譯時間  
  12.     string html = MyMVC.PageExecutor.Render(context, "/TestPage/WebFromPage.aspx", null);  
  13.  
  14.     Stopwatch watch = Stopwatch.StartNew();  
  15.     for( int i = 0; i < count; i++ )  
  16.         html = MyMVC.PageExecutor.Render(context, "/TestPage/WebFromPage.aspx", null);  
  17.     watch.Stop();  
  18.  
  19.     return watch.Elapsed.ToString();  

當我測試執(zhí)行10000次時,耗時:00:00:07.5607229

測試用例2:InlinePage.aspx

與測試用例1不同,測試用例2則完全不使用服務器控件。

頁面代碼:

 
 
 
 
  1. <%@ Page Language="C#" %> 
  2.  
  3.  
  4.  
  5.     PagePerformanceTest   http://www.cnblogs.com/fish-li/ 
  6.  
  7.  
  8.  
  9. This is InlinePage.aspx

     
  10.  
  11. <% foreach( BlogInfo b in XmlDb.Blogs ) { %> 
  12.     " target="_blank"><%= b.Title %> 
  13. <% } %> 
  14.  
  15.  
  16. <% foreach( BlogInfo b in XmlDb.Blogs ) { %> 
  17.     " target="_blank"><%= b.Title %> 
  18. <% } %> 
  19.  
  20.  
  21. <% foreach( BlogInfo b in XmlDb.Blogs ) { %> 
  22.     " target="_blank"><%= b.Title %> 
  23. <% } %> 
  24.  
  25.  
  26. <% foreach( BlogInfo b in XmlDb.Blogs ) { %> 
  27.     " target="_blank"><%= b.Title %> 
  28. <% } %> 
  29.  
  30.  
  31. <% foreach( BlogInfo b in XmlDb.Blogs ) { %> 
  32.     " target="_blank"><%= b.Title %> 
  33. <% } %> 
  34.  
  35.  
  36.  
  37.  

測試代碼:

 
 
 
 
  1. [Action]  
  2. public object Test2(string callTimes)  
  3. {  
  4.     int count = 0;  
  5.     int.TryParse(callTimes, out count);  
  6.     if( count <= 0 )  
  7.         return count;  
  8.  
  9.     HttpContext context = HttpContext.Current;  
  10.  
  11.     // 先執(zhí)行一次,排除編譯時間  
  12.     string html = MyMVC.PageExecutor.Render(context, "/TestPage/InlinePage.aspx", null);  
  13.  
  14.     Stopwatch watch = Stopwatch.StartNew();  
  15.     for( int i = 0; i < count; i++ )  
  16.         html = MyMVC.PageExecutor.Render(context, "/TestPage/InlinePage.aspx", null);  
  17.     watch.Stop();  
  18.  
  19.     return watch.Elapsed.ToString();  

當我測試執(zhí)行10000次時,耗時:00:00:01.2345842

分析優(yōu)化結(jié)果1

測試用例1執(zhí)行相同次數(shù)所花費的時間是測試用例2的6倍,為什么會這樣呢?

為了回答這個問題,我們首先要知道前面二個頁面在執(zhí)行時,它們是如何運行的。

說到這里,就不得不談ASP.NET的頁面編譯方式了。

ASP.NET的頁面編譯過程是個復雜的操作,其實我們可以不用關心頁面是如何編譯的,但要知道:頁面編譯后是什么樣的。

為了能直觀地了解頁面編譯后的樣子,我編譯了整個網(wǎng)站,并生成到一個DLL文件中,然后使用Reflector.exe來分析這個DLL的源代碼。

將網(wǎng)站編譯成一個DLL文件有二個方法:

  1. 安裝WebDeployment插件。
  2. 使用我的工具:FishAspnetTool

本文將使用FishAspnetTool來編譯測試網(wǎng)站獲得編譯后的DLL文件。

FishAspnetTool是什么?

FishAspnetTool是我在使用Visual Web Developer 2005時,為了方便編譯網(wǎng)站而寫的一個小工具。

下載地址:http://www.cnblogs.com/fish-li/archive/2011/10/30/2229497.html

注意:下載的是一個工具包,安裝后,從開始菜單中運行FishTools\FishAspnetTool即可。

下面是工具的運行截圖。

操作方法:

1. 點擊粉色按鈕,選擇網(wǎng)站路徑。

2. 單選按鈕選擇第2項。

3. 點擊【發(fā)布網(wǎng)站】按鈕。

在編譯網(wǎng)站之后,我就可以知道網(wǎng)站在運行時如何運行頁面了。

測試用例1的頁面,最后被編譯成這樣了:

 
 
 
 
  1. namespace ASP  
  2. {  
  3.     using System;  
  4.     using System.Diagnostics;  
  5.     using System.Runtime.CompilerServices;  
  6.     using System.Web;  
  7.     using System.Web.UI;  
  8.     using System.Web.UI.WebControls;  
  9.  
  10.     [CompilerGlobalScope]  
  11.     public class testpage_webfrompage_aspx : TestPage_WebFromPage, IHttpHandler  
  12.     {  
  13.         private static object __fileDependencies;  
  14.         private static bool __initialized;  
  15.  
  16.         [DebuggerNonUserCode]  
  17.         public testpage_webfrompage_aspx()  
  18.         {  
  19.             base.AppRelativeVirtualPath = "~/TestPage/WebFromPage.aspx";  
  20.             if (!__initialized)  
  21.             {  
  22.                 string[] virtualFileDependencies = new string[] { "~/TestPage/WebFromPage.aspx", "~/TestPage/WebFromPage.aspx.cs" };  
  23.                 __fileDependencies = base.GetWrappedFileDependencies(virtualFileDependencies);  
  24.                 __initialized = true;  
  25.             }  
  26.             base.Server.ScriptTimeout = 0x1c9c380;  
  27.         }  
  28.  
  29.         [DebuggerNonUserCode]  
  30.         private void __BuildControl__control10(Control __ctrl)  
  31.         {  
  32.             IParserAccessor accessor = __ctrl;  
  33.             accessor.AddParsedSubObject(new LiteralControl(""));  
  34.         }  
  35.  
  36.         [DebuggerNonUserCode]  
  37.         private void __BuildControl__control11(Control __ctrl)  
  38.         {  
  39.             IParserAccessor accessor = __ctrl;  
  40.             accessor.AddParsedSubObject(new LiteralControl("\r\n\t"));  
  41.             HyperLink link = this.__BuildControl__control12();  
  42.             accessor.AddParsedSubObject(link);  
  43.             accessor.AddParsedSubObject(new LiteralControl("\r\n"));  
  44.         }  
  45.  
  46.         [DebuggerNonUserCode]  
  47.         private HyperLink __BuildControl__control12()  
  48.         {  
  49.             HyperLink link = new HyperLink {  
  50.                 TemplateControl = this 
  51.             };  
  52.             link.ApplyStyleSheetSkin(this);  
  53.             link.ID = "link1";  
  54.             return link;  
  55.         }  
  56.  
  57.         [DebuggerNonUserCode]  
  58.         private void __BuildControl__control13(Control __ctrl)  
  59.         {  
  60.             IParserAccessor accessor = __ctrl;  
  61.             accessor.AddParsedSubObject(new LiteralControl(""));  
  62.         }  
  63.  
  64.         [DebuggerNonUserCode]  
  65.         private void __BuildControl__control14(Control __ctrl)  
  66.         {  
  67.             IParserAccessor accessor = __ctrl;  
  68.             accessor.AddParsedSubObject(new LiteralControl("\r\n\t"));  
  69.             HyperLink link = this.__BuildControl__control15();  
  70.             accessor.AddParsedSubObject(link);  
  71.             accessor.AddParsedSubObject(new LiteralControl("\r\n"));  
  72.         }  
  73.  
  74.         [DebuggerNonUserCode]  
  75.         private HyperLink __BuildControl__control15()  
  76.         {  
  77.             HyperLink link = new HyperLink {  
  78.                 TemplateControl = this 
  79.             };  
  80.             link.ApplyStyleSheetSkin(this);  
  81.             link.ID = "link1";  
  82.             return link;  
  83.         }  
  84.  
  85.         [DebuggerNonUserCode]  
  86.         private void __BuildControl__control16(Control __ctrl)  
  87.         {  
  88.             IParserAccessor accessor = __ctrl;  
  89.             accessor.AddParsedSubObject(new LiteralControl(""));  
  90.         }  
  91.  
  92.         [DebuggerNonUserCode]  
  93.         private void __BuildControl__control2(Control __ctrl)  
  94.         {  
  95.             IParserAccessor accessor = __ctrl;  
  96.             accessor.AddParsedSubObject(new LiteralControl("\r\n\t"));  
  97.             HyperLink link = this.__BuildControl__control3();  
  98.             accessor.AddParsedSubObject(link);  
  99.             accessor.AddParsedSubObject(new LiteralControl("\r\n"));  
  100.         }  
  101.  
  102.         [DebuggerNonUserCode]  
  103.         private HyperLink __BuildControl__control3()  
  104.         {  
  105.             HyperLink link = new HyperLink {  
  106.                 TemplateControl = this 
  107.             };  
  108.             link.ApplyStyleSheetSkin(this);  
  109.             link.ID = "link1";  
  110.             return link;  
  111.         }  
  112.  
  113.         [DebuggerNonUserCode]  
  114.         private void __BuildControl__control4(Control __ctrl)  
  115.         {  
  116.             IParserAccessor accessor = __ctrl;  
  117.             accessor.AddParsedSubObject(new LiteralControl(""));  
  118.         }  
  119.  
  120.         [DebuggerNonUserCode]  
  121.         private void __BuildControl__control5(Control __ctrl)  
  122.         {  
  123.             IParserAccessor accessor = __ctrl;  
  124.             accessor.AddParsedSubObject(new LiteralControl("\r\n\t"));  
  125.             HyperLink link = this.__BuildControl__control6();  
  126.             accessor.AddParsedSubObject(link);  
  127.             accessor.AddParsedSubObject(new LiteralControl("\r\n"));  
  128.         }  
  129.  
  130.         [DebuggerNonUserCode]  
  131.         private HyperLink __BuildControl__control6()  
  132.         {  
  133.             HyperLink link = new HyperLink {  
  134.                 TemplateControl = this 
  135.             };  
  136.             link.ApplyStyleSheetSkin(this);  
  137.             link.ID = "link1";  
  138.             return link;  
  139.         }  
  140.  
  141.         [DebuggerNonUserCode]  
  142.         private void __BuildControl__control7(Control __ctrl)  
  143.         {  
  144.             IParserAccessor accessor = __ctrl;  
  145.             accessor.AddParsedSubObject(new LiteralControl(""));  
  146.         }  
  147.  
  148.         [DebuggerNonUserCode]  
  149.         private void __BuildControl__control8(Control __ctrl)  
  150.         {  
  151.             IParserAccessor accessor = __ctrl;  
  152.             accessor.AddParsedSubObject(new LiteralControl("\r\n\t"));  
  153.             HyperLink link = this.__BuildControl__control9();  
  154.             accessor.AddParsedSubObject(link);  
  155.             accessor.AddParsedSubObject(new LiteralControl("\r\n"));  
  156.         }  
  157.  
  158.         [DebuggerNonUserCode]  
  159.         private HyperLink __BuildControl__control9()  
  160.         {  
  161.             HyperLink link = new HyperLink {  
  162.                 TemplateControl = this 
  163.             };  
  164.             link.ApplyStyleSheetSkin(this);  
  165.             link.ID = "link1";  
  166.             return link;  
  167.         }  
  168.  
  169.         [DebuggerNonUserCode]  
  170.         private Repeater __BuildControlrepeater1()  
  171.         {  
  172.             Repeater repeater = new Repeater();  
  173.             base.repeater1 = repeater;  
  174.             repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control2));  
  175.             repeater.FooterTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control4));  
  176.             repeater.ID = "repeater1";  
  177.             repeater.ItemDataBound += new RepeaterItemEventHandler(this.repeater1_ItemDataBound);  
  178.             return repeater;  
  179.         }  
  180.  
  181.         [DebuggerNonUserCode]  
  182.         private Repeater __BuildControlrepeater2()  
  183.         {  
  184.             Repeater repeater = new Repeater();  
  185.             base.repeater2 = repeater;  
  186.             repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control5));  
  187.             repeater.FooterTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control7));  
  188.             repeater.ID = "repeater2";  
  189.             repeater.ItemDataBound += new RepeaterItemEventHandler(this.repeater1_ItemDataBound);  
  190.             return repeater;  
  191.         }  
  192.  
  193.         [DebuggerNonUserCode]  
  194.         private Repeater __BuildControlrepeater3()  
  195.         {  
  196.             Repeater repeater = new Repeater();  
  197.             base.repeater3 = repeater;  
  198.             repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control8));  
  199.             repeater.FooterTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control10));  
  200.             repeater.ID = "repeater3";  
  201.             repeater.ItemDataBound += new RepeaterItemEventHandler(this.repeater1_ItemDataBound);  
  202.             return repeater;  
  203.         }  
  204.  
  205.         [DebuggerNonUserCode]  
  206.         private Repeater __BuildControlrepeater4()  
  207.         {  
  208.             Repeater repeater = new Repeater();  
  209.             base.repeater4 = repeater;  
  210.             repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control11));  
  211.             repeater.FooterTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control13));  
  212.             repeater.ID = "repeater4";  
  213.             repeater.ItemDataBound += new RepeaterItemEventHandler(this.repeater1_ItemDataBound);  
  214.             return repeater;  
  215.         }  
  216.  
  217.         [DebuggerNonUserCode]  
  218.         private Repeater __BuildControlrepeater5()  
  219.         {  
  220.             Repeater repeater = new Repeater();  
  221.             base.repeater5 = repeater;  
  222.             repeater.ItemTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control14));  
  223.             repeater.FooterTemplate = new CompiledTemplateBuilder(new BuildTemplateMethod(this.__BuildControl__control16));  
  224.             repeater.ID = "repeater5";  
  225.             repeater.ItemDataBound += new RepeaterItemEventHandler(this.repeater1_ItemDataBound);  
  226.  
    標題名稱:ASP.NET頁面優(yōu)化:性能提升8倍的方法
    本文鏈接:http://uogjgqi.cn/article/coijeep.html
掃二維碼與項目經(jīng)理溝通

我們在微信上24小時期待你的聲音

解答本文疑問/技術咨詢/運營咨詢/技術建議/互聯(lián)網(wǎng)交流