Asp. NET page optimization Performance 8 times times the method _ Practical skills

Source: Internet
Author: User
Tags httpcontext
To give you an intuitive understanding of the effects of optimization, I prepared the following screenshot of the test results:


Test environment:


1. Windows Server 2003 SP2


2. Viaual Studio 2008, use your own WebDev.WebServer.EXE to run the Web site program.


3. (ThinkPad SL510): Core2 T6670 2.2GHz, 4G memory





The number in the two red boxes reflects the execution time before and after optimization.





The number shows: Before and after the optimization, the execution time has more than 8 times times the difference.





Test Background



After looking at the results of the optimization, let me introduce: What is this test testing?





Now there are a lot of developers who do ASP.net, should start learning from the ASP.net WebForm programming model. Everyone likes to use server controls, regardless of output, use server controls. Sometimes in order for the page to render clean HTML code, some people choose to use simple server controls such as Repeater,literal. Perhaps some people think: I have not used the GridView such a powerful complex control, the page execution speed is very fast.





Is that so?





The starting point for today's Test starts with a simple server, and I'll do a series of performance optimizations two times.


Finally, the 3 results in the above diagram reflect the improvement process of two optimizations.





Before proceeding, there is one point I would like to explain:





The process of optimization involves the use of ASP.net server controls, and the test results are only a reference number.


If you think your development work is very dependent on the use of server controls,


Then the test results are meaningless to you, please do not care about the result.


test method
In this optimization process, I did not design a very complex test page, but a very simple test page, the page display effect is as follows:





This page is actually showing a bunch of hyperlinks, they come from my blog sidebar, "Recommended List", a total of 20 records, I let the page repeat 5 times output, that is, generated 100 hyperlinks.





This is how the data for the test is obtained:


I copied the HTML code for the "recommended leaderboard" of my blog sidebar and saved it to a file:





The site then extracts the link address and display text from this HTML code when it is initialized, and saves it to a bloginfo list with the following code:


Copy Code code as follows:

public class Bloginfo
{
public string Title;
public string Href;
}

public static Class Xmldb
{
public static list<bloginfo> Blogs {get; private set;}


public static void Loadblogs ()
{
String filePath = Path.Combine (Httpruntime.appdomainapppath, @ "app_data\recommendlist.html");

XElement html = xelement.parse (System.IO.File.ReadAllText (FilePath));

Blogs =
(from a in HTML.) Elements ("Li"). Elements ("a")
Select New Bloginfo {Title = a.value, href = A.attribute ("href"). Value}). ToList ();
}
}



When testing, the contents of the Xmldb.blogs are displayed in the Web page.


I think this test is relatively close to the real development.





Here's another question: How do I test the speed of a page?





Although it's a simple way to create a HttpWebRequest access page, I'm not going to do that.


Because the call is initiated from HttpWebRequest to get the result, it is mixed with additional invocation overhead in addition to the execution time of the page. In the end, I chose to loop through the Server.Execute to execute the page in an HTTP request, and to count the time. In fact, how to choose the test method, for two test subjects also said, are fair. Just say: Minimizing some of the additional call overhead will make the test results more varied and more obvious.





Description: In order to test the code write simple, I used the MYMVC framework.


Test Case 1:webfrompage.aspx
The test background and test methods are described earlier. Now we're going to introduce the 1th test case, which uses the most classical notation in the WebForm programming model.


Page code:


Copy Code code as follows:



&lt;%@ Page language= "C #" codefile= "WebFromPage.aspx.cs" inherits= "Testpage_webfrompage"%&gt;


&lt;html xmlns= "http://www.w3.org/1999/xhtml" &gt;


&lt;head&gt;


&lt;title&gt;pageperformancetest http://www.cnblogs.com/fish-li/&lt;/title&gt;


&lt;/head&gt;


&lt;body&gt;


&lt;p&gt;this is webfrompage.aspx&lt;/p&gt;


&lt;asp:repeater id= "Repeater1" runat= "Server" onitemdatabound= "Repeater1_itemdatabound" &gt;


&lt;ItemTemplate&gt;


&lt;asp:hyperlink id= "Link1" runat= "Server" &gt;&lt;/asp:hyperlink&gt;&lt;br/&gt;


&lt;/ItemTemplate&gt;


&LT;FOOTERTEMPLATE&GT;&LT;HR/&gt;&lt;/footertemplate&gt;


&lt;/asp:Repeater&gt;


&lt;asp:repeater id= "Repeater2" runat= "Server" onitemdatabound= "Repeater1_itemdatabound" &gt;


&lt;ItemTemplate&gt;


&lt;asp:hyperlink id= "Link1" runat= "Server" &gt;&lt;/asp:hyperlink&gt;&lt;br/&gt;


&lt;/ItemTemplate&gt;


&LT;FOOTERTEMPLATE&GT;&LT;HR/&gt;&lt;/footertemplate&gt;


&lt;/asp:Repeater&gt;


&lt;asp:repeater id= "Repeater3" runat= "Server" onitemdatabound= "Repeater1_itemdatabound" &gt;


&lt;ItemTemplate&gt;


&lt;asp:hyperlink id= "Link1" runat= "Server" &gt;&lt;/asp:hyperlink&gt;&lt;br/&gt;


&lt;/ItemTemplate&gt;


&LT;FOOTERTEMPLATE&GT;&LT;HR/&gt;&lt;/footertemplate&gt;


&lt;/asp:Repeater&gt;


&lt;asp:repeater id= "repeater4" runat= "Server" onitemdatabound= "Repeater1_itemdatabound" &gt;


&lt;ItemTemplate&gt;


&lt;asp:hyperlink id= "Link1" runat= "Server" &gt;&lt;/asp:hyperlink&gt;&lt;br/&gt;


&lt;/ItemTemplate&gt;


&LT;FOOTERTEMPLATE&GT;&LT;HR/&gt;&lt;/footertemplate&gt;


&lt;/asp:Repeater&gt;


&lt;asp:repeater id= "Repeater5" runat= "Server" onitemdatabound= "Repeater1_itemdatabound" &gt;


&lt;ItemTemplate&gt;


&lt;asp:hyperlink id= "Link1" runat= "Server" &gt;&lt;/asp:hyperlink&gt;&lt;br/&gt;


&lt;/ItemTemplate&gt;


&LT;FOOTERTEMPLATE&GT;&LT;HR/&gt;&lt;/footertemplate&gt;


&lt;/asp:Repeater&gt;





&lt;/body&gt;


&lt;/html&gt;





CodeFile code for the page:


Copy Code code as follows:

public partial class TestPage_WebFromPage:System.Web.UI.Page
{
protected override void OnLoad (EventArgs e)
{
Base. OnLoad (e);
Repeater1. DataSource = Xmldb.blogs;
Repeater1. DataBind ();
Repeater2. DataSource = Xmldb.blogs;
Repeater2. DataBind ();
Repeater3. DataSource = Xmldb.blogs;
Repeater3. DataBind ();
Repeater4. DataSource = Xmldb.blogs;
Repeater4. DataBind ();
Repeater5. DataSource = Xmldb.blogs;
Repeater5. DataBind ();
}
protected void Repeater1_itemdatabound (object sender, RepeaterItemEventArgs e)
{
if (E.item.itemtype = = ListItemType.Item) {
Bloginfo blog = e.item.dataitem as Bloginfo;
HyperLink Link1 = E.item.findcontrol ("Link1") as HyperLink;
Link1. NavigateUrl = blog. Href;
Link1. Text = blog. Title;
}
}
}



Test code:


Copy Code code as follows:

[Action]
public Object Test1 (string calltimes)
{
int count = 0;
Int. TryParse (Calltimes, out count);
if (Count <= 0)
return count;
HttpContext context = HttpContext.Current;
Execute first, excluding compile time
String html = MyMVC.PageExecutor.Render (context, "/testpage/webfrompage.aspx", null);
Stopwatch watch = Stopwatch.startnew ();
for (int i = 0; i < count; i++)
HTML = MyMVC.PageExecutor.Render (context, "/testpage/webfrompage.aspx", null);
Watch. Stop ();
Return watch. Elapsed.tostring ();
}



When I test execution 10,000 times, time consuming: 00:00:07.5607229


Back to Top


Test Case 2:inlinepage.aspx


Unlike test Case 1, test Case 2 does not use server controls at all.


Page code:


Copy Code code as follows:



&lt;%@ Page language= "C #"%&gt;


&lt;html xmlns= "http://www.w3.org/1999/xhtml" &gt;


&lt;head&gt;


&lt;title&gt;pageperformancetest http://www.cnblogs.com/fish-li/&lt;/title&gt;


&lt;/head&gt;


&lt;body&gt;


&lt;p&gt;this is inlinepage.aspx&lt;/p&gt;


&lt;% foreach (Bloginfo b in xmldb.blogs) {%&gt;


&lt;a href= "&lt;%= b.href%&gt;" target= "_blank" &gt;&lt;%= b.title,%&gt;&lt;/a&gt;&lt;br/&gt;


&lt;%}%&gt;


&lt;hr/&gt;


&lt;% foreach (Bloginfo b in xmldb.blogs) {%&gt;


&lt;a href= "&lt;%= b.href%&gt;" target= "_blank" &gt;&lt;%= b.title,%&gt;&lt;/a&gt;&lt;br/&gt;


&lt;%}%&gt;


&lt;hr/&gt;


&lt;% foreach (Bloginfo b in xmldb.blogs) {%&gt;


&lt;a href= "&lt;%= b.href%&gt;" target= "_blank" &gt;&lt;%= b.title,%&gt;&lt;/a&gt;&lt;br/&gt;


&lt;%}%&gt;


&lt;hr/&gt;


&lt;% foreach (Bloginfo b in xmldb.blogs) {%&gt;


&lt;a href= "&lt;%= b.href%&gt;" target= "_blank" &gt;&lt;%= b.title,%&gt;&lt;/a&gt;&lt;br/&gt;


&lt;%}%&gt;


&lt;hr/&gt;


&lt;% foreach (Bloginfo b in xmldb.blogs) {%&gt;


&lt;a href= "&lt;%= b.href%&gt;" target= "_blank" &gt;&lt;%= b.title,%&gt;&lt;/a&gt;&lt;br/&gt;


&lt;%}%&gt;


&lt;hr/&gt;


&lt;/body&gt;


&lt;/html&gt;





Test code:


Copy Code code as follows:

[Action]
public Object Test2 (string calltimes)
{
int count = 0;
Int. TryParse (Calltimes, out count);
if (Count <= 0)
return count;
HttpContext context = HttpContext.Current;
Execute first, excluding compile time
String html = MyMVC.PageExecutor.Render (context, "/testpage/inlinepage.aspx", null);
Stopwatch watch = Stopwatch.startnew ();
for (int i = 0; i < count; i++)
HTML = MyMVC.PageExecutor.Render (context, "/testpage/inlinepage.aspx", null);
Watch. Stop ();
Return watch. Elapsed.tostring ();
}



When I test execution 10,000 times, time consuming: 00:00:01.2345842


Back to the top of


Analysis Optimization Results 1


Test Case 1 takes the same number of times as the test Case 2 6 times times, why is that so?


To answer this question, we first need to know how the previous two pages work when they are executed.


Speaking of this, we have to talk about the asp.net of the page to compile the way.


Asp. NET page compilation process is a complex operation, in fact, we can not care about how the page is compiled,


But you know: what is the page after compiling it.


To get an intuitive picture of how the page was compiled, I compiled the entire Web site and built it into a DLL file, and then used Reflector.exe to parse the DLL's source code.


There are two ways to compile a Web site into a DLL file:


1. Install the Webdeployment plugin.


2. Use my tools: Fishaspnettool


This article will use Fishaspnettool to compile the test Web site to obtain the compiled DLL file.


What is Fishaspnettool?


Fishaspnettool is a gadget I wrote when I was using the Visual Web Developer 2005 to make it easier to compile a Web site.


Download Address: http://www.jb51.net/article/29875.htm


Note: The download is a toolkit, after installation, run Fishtools\fishaspnettool from the Start menu.


Below is a screenshot of the tool's run.





Action method:


1. Click on the Pink button to select the site path.


2. radio button Select Item 2nd.


3. Click the "Publish Website" button.


After compiling the website, I can know how the Web site runs the page at run time.


The page of test Case 1 was finally compiled like this:


Copy Code code as follows:



Namespace ASP


{


Using System;


Using System.Diagnostics;


Using System.Runtime.CompilerServices;


Using System.Web;


Using System.Web.UI;


Using System.Web.UI.WebControls;


[Compilerglobalscope]


public class Testpage_webfrompage_aspx:testpage_webfrompage, IHttpHandler


{


private static object __filedependencies;


private static bool __initialized;


[Debuggernonusercode]


Public testpage_webfrompage_aspx ()


{


Base. Apprelativevirtualpath = "~/testpage/webfrompage.aspx";


if (!__initialized)


{


string[] virtualfiledependencies = new string[] {"~/testpage/webfrompage.aspx", "~/testpage/webfrompage.aspx.cs"};


__filedependencies = base. Getwrappedfiledependencies (virtualfiledependencies);


__initialized = true;


}


Base. Server.ScriptTimeout = 0x1c9c380;


}


[Debuggernonusercode]


private void __buildcontrol__control10 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("&lt;hr/&gt;"));


}


[Debuggernonusercode]


private void __buildcontrol__control11 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\t"));


HyperLink link = this.__buildcontrol__control12 ();


Accessor. AddParsedSubObject (link);


Accessor. AddParsedSubObject (New LiteralControl ("&lt;br/&gt;\r\n"));


}


[Debuggernonusercode]


Private HyperLink __buildcontrol__control12 ()


{


HyperLink link = new HyperLink {


TemplateControl = This


};


Link. Applystylesheetskin (this);


Link.id = "Link1";


return link;


}


[Debuggernonusercode]


private void __buildcontrol__control13 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("&lt;hr/&gt;"));


}


[Debuggernonusercode]


private void __buildcontrol__control14 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\t"));


HyperLink link = this.__buildcontrol__control15 ();


Accessor. AddParsedSubObject (link);


Accessor. AddParsedSubObject (New LiteralControl ("&lt;br/&gt;\r\n"));


}


[Debuggernonusercode]


Private HyperLink __buildcontrol__control15 ()


{


HyperLink link = new HyperLink {


TemplateControl = This


};


Link. Applystylesheetskin (this);


Link.id = "Link1";


return link;


}


[Debuggernonusercode]


private void __buildcontrol__control16 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("&lt;hr/&gt;"));


}


[Debuggernonusercode]


private void __buildcontrol__control2 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\t"));


HyperLink link = this.__buildcontrol__control3 ();


Accessor. AddParsedSubObject (link);


Accessor. AddParsedSubObject (New LiteralControl ("&lt;br/&gt;\r\n"));


}


[Debuggernonusercode]


Private HyperLink __buildcontrol__control3 ()


{


HyperLink link = new HyperLink {


TemplateControl = This


};


Link. Applystylesheetskin (this);


Link.id = "Link1";


return link;


}


[Debuggernonusercode]


private void __buildcontrol__control4 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("&lt;hr/&gt;"));


}


[Debuggernonusercode]


private void __buildcontrol__control5 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\t"));


HyperLink link = this.__buildcontrol__control6 ();


Accessor. AddParsedSubObject (link);


Accessor. AddParsedSubObject (New LiteralControl ("&lt;br/&gt;\r\n"));


}


[Debuggernonusercode]


Private HyperLink __buildcontrol__control6 ()


{


HyperLink link = new HyperLink {


TemplateControl = This


};


Link. Applystylesheetskin (this);


Link.id = "Link1";


return link;


}


[Debuggernonusercode]


private void __buildcontrol__control7 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("&lt;hr/&gt;"));


}


[Debuggernonusercode]


private void __buildcontrol__control8 (Control __ctrl)


{


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\t"));


HyperLink link = this.__buildcontrol__control9 ();


Accessor. AddParsedSubObject (link);


Accessor. AddParsedSubObject (New LiteralControl ("&lt;br/&gt;\r\n"));


}


[Debuggernonusercode]


Private HyperLink __buildcontrol__control9 ()


{


HyperLink link = new HyperLink {


TemplateControl = This


};


Link. Applystylesheetskin (this);


Link.id = "Link1";


return link;


}


[Debuggernonusercode]


Private Repeater __buildcontrolrepeater1 ()


{


Repeater Repeater = new Repeater ();


Base.repeater1 = repeater;


Repeater. ItemTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (this.__buildcontrol__control2));


Repeater. FooterTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL4));


Repeater.id = "Repeater1";


Repeater. ItemDataBound + = new Repeateritemeventhandler (this.repeater1_itemdatabound);


return repeater;


}


[Debuggernonusercode]


Private Repeater __buildcontrolrepeater2 ()


{


Repeater Repeater = new Repeater ();


Base.repeater2 = repeater;


Repeater. ItemTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL5));


Repeater. FooterTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL7));


Repeater.id = "Repeater2";


Repeater. ItemDataBound + = new Repeateritemeventhandler (this.repeater1_itemdatabound);


return repeater;


}


[Debuggernonusercode]


Private Repeater __buildcontrolrepeater3 ()


{


Repeater Repeater = new Repeater ();


Base.repeater3 = repeater;


Repeater. ItemTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL8));


Repeater. FooterTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL10));


Repeater.id = "Repeater3";


Repeater. ItemDataBound + = new Repeateritemeventhandler (this.repeater1_itemdatabound);


return repeater;


}


[Debuggernonusercode]


Private Repeater __buildcontrolrepeater4 ()


{


Repeater Repeater = new Repeater ();


Base.repeater4 = repeater;


Repeater. ItemTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL11));


Repeater. FooterTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL13));


Repeater.id = "Repeater4";


Repeater. ItemDataBound + = new Repeateritemeventhandler (this.repeater1_itemdatabound);


return repeater;


}


[Debuggernonusercode]


Private Repeater __buildcontrolrepeater5 ()


{


Repeater Repeater = new Repeater ();


BASE.REPEATER5 = repeater;


Repeater. ItemTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL14));


Repeater. FooterTemplate = new Compiledtemplatebuilder (new Buildtemplatemethod (THIS.__BUILDCONTROL__CONTROL16));


Repeater.id = "Repeater5";


Repeater. ItemDataBound + = new Repeateritemeventhandler (this.repeater1_itemdatabound);


return repeater;


}


[Debuggernonusercode]


private void __buildcontroltree (testpage_webfrompage_aspx __ctrl)


{


__ctrl. EnableViewState = false;


__ctrl. enableViewStateMac = false;


This. InitializeCulture ();


IParserAccessor accessor = __ctrl;


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n&lt;html xmlns=\" http://www.w3.org/1999/xhtml\ "&gt;\r\n&lt;head") &gt;\r\n &lt;title&gt;pageperformancetest http://www.cnblogs.com/fish-li/&lt;/title&gt;\r\n&lt;/head&gt;\r\n&lt; Body&gt;\r\n\r\n&lt;p&gt;this is webfrompage.aspx&lt;/p&gt;\r\n\r\n "));


Repeater Repeater = This.__buildcontrolrepeater1 ();


Accessor. AddParsedSubObject (repeater);


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n"));


Repeater repeater2 = This.__buildcontrolrepeater2 ();


Accessor. AddParsedSubObject (REPEATER2);


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n"));


Repeater Repeater3 = This.__buildcontrolrepeater3 ();


Accessor. AddParsedSubObject (REPEATER3);


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n"));


Repeater repeater4 = This.__buildcontrolrepeater4 ();


Accessor. AddParsedSubObject (REPEATER4);


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n"));


Repeater Repeater5 = This.__buildcontrolrepeater5 ();


Accessor. AddParsedSubObject (REPEATER5);


Accessor. AddParsedSubObject (New LiteralControl ("\r\n\r\n\r\n&lt;/body&gt;\r\n&lt;/html&gt;\r\n"));


}


[Debuggernonusercode]


protected override void FrameworkInitialize ()


{


Base. FrameworkInitialize ();


This.__buildcontroltree (this);


Base. Addwrappedfiledependencies (__filedependencies);


Base. Request.validateinput ();


}


[Debuggernonusercode]


public override int GetTypeHashCode ()


{


return-781896338;


}


[Debuggernonusercode]


public override void ProcessRequest (HttpContext context)


{


Base. ProcessRequest (context);


}


protected override bool Supportautoevents


{


Get


{


return false;


}


}


}


}





From the results of this compilation we can see that all the text on the page is finally wrapped into LiteralControl.


When rendered in a page, it is the Render method that loops through each control to eventually generate HTML results.


The page of test Case 2 is compiled into this sample:


Copy Code code as follows:



Namespace ASP


{


Using System;


Using System.Diagnostics;


Using System.Runtime.CompilerServices;


Using System.Web;


Using System.Web.Profile;


Using System.Web.UI;


[Compilerglobalscope]


public class Testpage_inlinepage_aspx:page, IHttpHandler


{


private static object __filedependencies;


private static bool __initialized;


[Debuggernonusercode]


Public testpage_inlinepage_aspx ()


{


Base. Apprelativevirtualpath = "~/testpage/inlinepage.aspx";


if (!__initialized)


{


string[] virtualfiledependencies = new string[] {"~/testpage/inlinepage.aspx"};


__filedependencies = base. Getwrappedfiledependencies (virtualfiledependencies);


__initialized = true;


}


Base. Server.ScriptTimeout = 0x1c9c380;


}


[Debuggernonusercode]


private void __buildcontroltree (testpage_inlinepage_aspx __ctrl)


{


__ctrl. EnableViewState = false;


__ctrl. enableViewStateMac = false;


This. InitializeCulture ();


__ctrl. Setrendermethoddelegate (New Rendermethod (this.__render__control1));


}


private void __render__control1 (HtmlTextWriter __w, control Parametercontainer)


{


__w.write ("\r\n\r\n&lt;html xmlns=\" http://www.w3.org/1999/xhtml\ "&gt;\r\n&lt;head&gt;\r\n &lt;title&gt; Pageperformancetest http://www.cnblogs.com/fish-li/&lt;/title&gt;\r\n&lt;/head&gt;\r\n&lt;body&gt;\r\n\r\n&lt;p &gt;this is inlinepage.aspx&lt;/p&gt;\r\n\r\n ");


foreach (Bloginfo info in xmldb.blogs)


{


__w.write ("\r\n\t&lt;a href=\");


__w.write (info. HREF);


__w.write ("target=\" _blank\ "&gt;");


__w.write (info. Title);


__w.write ("&lt;/a&gt;&lt;br/&gt;\r\n");


}


__w.write ("\r\n&lt;hr/&gt;\r\n\r\n");


foreach (Bloginfo info2 in Xmldb.blogs)


{


__w.write ("\r\n\t&lt;a href=\");


__w.write (Info2. HREF);


__w.write ("target=\" _blank\ "&gt;");


__w.write (Info2. Title);


__w.write ("&lt;/a&gt;&lt;br/&gt;\r\n");


}


__w.write ("\r\n&lt;hr/&gt;\r\n\r\n");


foreach (Bloginfo Info3 in Xmldb.blogs)


{


__w.write ("\r\n\t&lt;a href=\");


__w.write (Info3. HREF);


__w.write ("target=\" _blank\ "&gt;");


__w.write (Info3. Title);


__w.write ("&lt;/a&gt;&lt;br/&gt;\r\n");


}


__w.write ("\r\n&lt;hr/&gt;\r\n\r\n");


foreach (Bloginfo Info4 in Xmldb.blogs)


{


__w.write ("\r\n\t&lt;a href=\");


__w.write (Info4. HREF);


__w.write ("target=\" _blank\ "&gt;");


__w.write (Info4. Title);


__w.write ("&lt;/a&gt;&lt;br/&gt;\r\n");


}


__w.write ("\r\n&lt;hr/&gt;\r\n\r\n");


foreach (Bloginfo info5 in Xmldb.blogs)


{


__w.write ("\r\n\t&lt;a href=\");


__w.write (Info5. HREF);


__w.write ("target=\" _blank\ "&gt;");


__w.write (Info5. Title);


__w.write ("&lt;/a&gt;&lt;br/&gt;\r\n");


}


__w.write ("\r\n&lt;hr/&gt;\r\n\r\n&lt;/body&gt;\r\n&lt;/html&gt;\r\n");


}


[Debuggernonusercode]


protected override void FrameworkInitialize ()


{


Base. FrameworkInitialize ();


This.__buildcontroltree (this);


Base. Addwrappedfiledependencies (__filedependencies);


Base. Request.validateinput ();


}


[Debuggernonusercode]


public override int GetTypeHashCode ()


{


return-1307842476;


}


[Debuggernonusercode]


public override void ProcessRequest (HttpContext context)


{


Base. ProcessRequest (context);


}


Protected Global_asax ApplicationInstance


{


Get


{


Return (Global_asax) this. Context.applicationinstance;


}


}


Protected DefaultProfile Profile


{


Get


{


Return (DefaultProfile) this. Context.profile;


}


}


protected override bool Supportautoevents


{


Get


{


return false;


}


}


}


}





Note the following key code: they are so important.


Copy Code code as follows:

private void __buildcontroltree (testpage_inlinepage_aspx __ctrl)
{
// .......
__ctrl. Setrendermethoddelegate (New Rendermethod (this.__render__control1));
}
private void __render__control1 (HtmlTextWriter __w, control Parametercontainer)
{



Testpage_inlinepage_aspx is completely different from the testpage_webfrompage_aspx compilation results.


The biggest difference in Testpage_inlinepage_aspx has a method: __render__control1


In this method, the content of the page is written directly into the HtmlTextWriter object.


There is one more thing I want to tell you: the output of each control is to write its own display code to the HtmlTextWriter object at the end.


Therefore, it is clear from here that the testpage_inlinepage_aspx execution speed is much faster,


Because:


1. It does not have a server control.


2. Recursive loops are no longer needed for each control, and the invocation overhead of each control's lifecycle is also saved.


3. The pressure on the GC will be much smaller without creating those server control objects.


4. The output mode is more efficient.


With the previous analysis, you now understand why the two-page execution rate is 6 times times the difference.


There seems to be a little explanation: How is __render__control1 called?


As we all know, the WebForm programming model, represented by an ASPX page, has a feature to perform: recursively loops each control.


The page is output in the render phase, and the HTML code of the page is also exported to the HtmlTextWriter object at that stage.


However, Testpage_inlinepage_aspx does not have any control, how should it be recursive?


Indeed, many books, as well as technical data, say that in the render phase, each control is recursively cycled and the control's Render method is invoked.


In fact, this statement is not accurate. The Render method of control invokes the following method at run time:


Copy Code code as follows:

Internal void Renderchildreninternal (HtmlTextWriter writer, ICollection children)
{
if (this. Rarefields!= null) && (this. Rarefields.rendermethod!= null))
{
Writer. Beginrender ();
This. Rarefields.rendermethod (writer, this);
Writer. Endrender ();
}
else if (children!= null)
{
foreach (Control in children)
{
Control. RenderControl (writer);
}
}
}



In this code, there is an important if...else ... To judge, to put it simply, to avoid invoking the __render__control1 method described above.


As you can see from the code, if you are entering an IF statement block, you do not have to loop each control recursively and call the control's Render method.


So how do you get into an IF statement block?


The answer is: Invoke the Control.setrendermethoddelegate method.


This call is in the testpage_inlinepage_aspx compilation generation code.


For this method, the MSDN explanation is ambiguous:


This API supports the. NET Framework infrastructure and is not suitable for direct use in your code.


Assign an event handler delegate to render the server control and its contents to the parent control.


Back to the top of


Test Case 3:inlineusercontrol.ascx


In test case 3, I move the code in the page for output to a user control.


The code for the user control is omitted here and is essentially consistent with the code for test Case 2. The results of the compilation are basically the same.


Test code:


Copy Code code as follows:

[Action]
public Object Test3 (string calltimes)
{
int count = 0;
Int. TryParse (Calltimes, out count);
if (Count <= 0)
return count;
Execute first, excluding compile time
String html = MyMVC.UcExecutor.Render ("/usercontrol/inlineusercontrol.ascx", null);
Stopwatch watch = Stopwatch.startnew ();
for (int i = 0; i < count; i++)
html = MyMVC.UcExecutor.Render ("/usercontrol/inlineusercontrol.ascx", null);
Watch. Stop ();
Return watch. Elapsed.tostring ();
}



When I test execution 10,000 times, time consuming: 00:00:00.9132738


It's a little fast.


Description: For this performance optimization, the MYMVC framework has also made a little adjustment. If you have previously downloaded this frame, please download it again.


Back to the top of


Analysis Optimization Results 2


Through the previous analysis, we know that you can make a page run much faster without creating a server control object and not calling their lifecycle.


Have you ever imagined that the page also has a life cycle, and that the life cycle is longer, and will it be quicker to omit it?


However, the Render method is not a public method and we cannot call it directly, but we can invoke the RenderControl method to implement this process.


Any server control cannot be used, including the motherboard page, because it skips the life cycle of the page. So I chose to move the piece of code from the previous test to the user control and then load the user control into the page to test.


Test Case 3 compared to test Case 2, during testing, the speed is faster because the page's lifecycle is skipped.


Well, basically, that's the simple reason.


Because this method does not have any control lifecycle, the speed is the fastest.


After this series of optimizations, the page's execution time is eventually reduced from 00:00:07.5607229 to 00:00:00.9132738





Click here to download the sample code
Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.