回答讨饭猫之asp.net优化(一)

80酷酷网    80kuku.com

  asp.net|优化

Performance Tuning Tips

Any programming model has its common performance pitfalls, and ASP.NET is no exception. This section describes some of the ways in which you can avoid performance bottlenecks in your code.
  1. Disable Session State when not in use: Not all applications or pages require per-user session state. If it is not required, disable it completely. This is easily accomplished using a page-level directive, such as the following:
    <% Page EnableSessionState="false" %>

    Note: If a page requires access to session variables but does not create or modify them, set the value of the directive to ReadOnly. Session State can also be disabled for Web Service methods. See Using Objects and Intrinsics in the Web Services section.
  2. Choose your Session State provider carefully: ASP.NET provides three distinct ways to store session data for your application: in-process session state, out-of-process session state as a Windows Service, and out-of-process session state in a SQL database. Each has its advantages, but in-process session state is by far the fastest solution. If you are only storing small amounts of volatile data in session state you should use the in-process provider. The out-of-process solutions are primarily useful in Web garden and Web farm scenarios or in situations in which data cannot be lost in the event of a server/process restart.
  3. Avoid excessive round trips to the server: The Web Forms page framework is one of the best features of ASP.NET, because it can dramatically reduce the amount of code you need to write to accomplish a task. Programmatic access to page elements using server controls and the postback event handling model are arguably the most time-saving features. However, there are appropriate and inappropriate ways to use these features, and it is important to know when it is appropriate to use them.
    An application typically needs to make a round trip to the server only when retrieving data or storing data. Most data manipulations can take place on the client between round trips. For example, validating form entries can often take place on the client before the user submits data. In general, if you do not need to relay information back to the server, then you should not make a round trip to the server.
    If you are writing your own server controls, consider having them render client-side code for up-level (ECMAScript-capable) browsers. By employing "smart" controls, you can dramatically reduce the number of unecessary hits to your Web server.
  4. Use Page.IsPostback to avoid extra work on a round trip: If you are handling server control postbacks, you often need to execute different code the first time the page is requested from the code you do use for the round trip when an event is fired. If you check the Page.IsPostBack property, your code can execute conditionally, depending on whether there is an initial request for the page or a responce to a server control event. It might seem obvious to do this, but in practice it is possible to omit this check without changing the behavior of the page. For example:
        td.code {      padding:0,10,0,10;      border-style:solid;      border-width:1;      border-bottom:0;      border-top:0;      border-right:0;      border-color:cccccc;      background-color:ffffee    }    td.tab {      text-align:center;      font:8pt verdana;      width:15%;      padding:3,3,3,3;      border-style:solid;      border-width:1;      border-right:0;      border-color:black;      background-color:eeeeee;      cursor:hand    }    td.backtab {      text-align:center;      font: 8pt verdana;      width:15%;      padding:3,3,3,3;      border-style:solid;      border-width:1;      border-right:0;      border-color:black;      background-color:cccccc;      cursor:hand    }    td.space {      width:55%;      font: 8pt verdana;      padding:0,0,0,0;      border-style:solid;      border-bottom:0;      border-right:0;      border-width:1;      border-color:cccccc;      border-left-color:black;      background-color:white    }  
    <script language="C#" runat="server">    public DataSet ds;    ...    void Page_Load(Object sender, EventArgs e) {        // ...set up a connection and command here...        if (!Page.IsPostBack) {            String query = "select * from Authors where FirstName like '%JUSTIN%'";            myCommand.Fill(ds, "Authors");            myDataGrid.DataBind();        }    }    void Button_Click(Object sender, EventArgs e) {        String query = "select * from Authors where FirstName like '%BRAD%'";        myCommand.Fill(ds, "Authors");        myDataGrid.DataBind();    }</script><form runat="server">  <asp:datagrid datasource='<%# ds.DefaultView %>' runat="server"/>
      <asp:button onclick="Button_Click" runat="server"/></form>
    <script language="VB" runat="server">    Public ds As DataSet    ...    Sub Page_Load(sender As Object, e As EventArgs)        ' ...set up a connection and command here...        If Not (Page.IsPostBack)            Dim query As String = "select * from Authors where FirstName like '%JUSTIN%'"            myCommand.Fill(ds, "Authors")            myDataGrid.DataBind()        End If    End Sub    Sub Button_Click(sender As Object, e As EventArgs)        Dim query As String = "select * from Authors where FirstName like '%BRAD%'"        myCommand.Fill(ds, "Authors")        myDataGrid.DataBind()    End Sub</script><form runat="server">  <asp:datagrid datasource='<%# ds.Tables["Authors"].DefaultView %>' runat="server"/>
      <asp:button onclick="Button_Click" runat="server"/></form>
    <script language="JScript" runat="server">    public var ds:DataSet;    ...    function Page_Load(sender:Object, e:EventArgs) : void {        // ...set up a connection and command here...        if (!Page.IsPostBack) {            var query:String = "select * from Authors where FirstName like '%JUSTIN%'";            myCommand.Fill(ds, "Authors");            myDataGrid.DataBind();        }    }    function Button_Click(sender:Object, e:EventArgs) : void {        var query:String = "select * from Authors where FirstName like '%BRAD%'";        myCommand.Fill(ds, "Authors");        myDataGrid.DataBind();    }</script><form runat="server">  <asp:datagrid datasource='<%# ds.DefaultView %>' runat="server"/>
      <asp:button onclick="Button_Click" runat="server"/></form>
    C# VB JScript
    The Page_Load event executes on every request, so we checked Page.IsPostBack so that the first query does not execute when we process the Button_Click event postback. Note that even without this check our page would behave identically, since the binding from the first query would be overturned by the call to DataBind in the event handler. Keep in mind that it can be easy to overlook this simple performance improvement when you write your pages.
  5. Use server controls sparingly and appropriately: Even though it is extremely easy to use, a server control might not always be the best choice. In many cases, a simple rendering or databinding substitution will accomplish the same thing. For example:
    <script language="C#" runat="server">    public String imagePath;    void Page_Load(Object sender, EventArgs e) {        //...retrieve data for imagePath here...        DataBind();    }</script><%-- the span and img server controls are unecessary...--%>The path to the image is: <span innerhtml='<%# imagePath %>' runat="server"/>
    <img src='<%# imagePath %>' runat="server"/>

    <%-- use databinding to substitute literals instead...--%>The path to the image is: <%# imagePath %>
    <img src='<%# imagePath %>' />

    <%-- or a simple rendering expression...--%>The path to the image is: <%= imagePath %>
    <img src='<%= imagePath %>' />
    <script language="VB" runat="server">    Public imagePath As String    Sub Page_Load(sender As Object, e As EventArgs)        '...retrieve data for imagePath here...        DataBind()    End Sub</script><%--the span and img server controls are unecessary...--%>The path to the image is: <span innerhtml='<%# imagePath %>' runat="server"/>
    <img src='<%# imagePath %>' runat="server"/>

    <%-- use databinding to substitute literals instead...--%>The path to the image is: <%# imagePath %>
    <img src='<%# imagePath %>' />

    <%-- or a simple rendering expression...--%>The path to the image is: <%= imagePath %>
    <img src='<%= imagePath %>' />
    <script language="JScript" runat="server">    public var imagePath:String;    function Page_Load(sender:Object, e:EventArgs) : void {        //...retrieve data for imagePath here...        DataBind();    }</script><%-- the span and img server controls are unecessary...--%>The path to the image is: <span innerhtml='<%# imagePath %>' runat="server"/>
    <img src='<%# imagePath %>' runat="server"/>

    <%-- use databinding to substitute literals instead...--%>The path to the image is: <%# imagePath %>
    <img src='<%# imagePath %>' />

    <%-- or a simple rendering expression...--%>The path to the image is: <%= imagePath %>
    <img src='<%= imagePath %>' />
    C# VB JScript
    In this example, a server control is not needed to substitute values into the resulting HTML sent back to the client. There are many other cases where this technique works just fine, even in server control templates. However, if you want to programmatically manipulate the control's properties, handle events from it, or take advantage of its state preservation, then a server control would be appropriate. You should examine your use of server controls and look for code you can optimize.
  6. Avoid excessive server control view state: Automatic state management is a feature that enables server controls to re-populate their values on a round trip without requiring you to write any code. This feature is not free however, since the state of a control is passed to and from the server in a hidden form field. You should be aware of when ViewState is helping you and when it is not. For example, if you are binding a control to data on every round trip (as in the datagrid example in tip #4), then you do not need the control to maintain it's view state, since you will wipe out any re-populated data in any case.
    ViewState is enabled for all server controls by default. To disable it, set the MaintainState property of the control to false, as in the following example:
    <asp:datagrid MaintainState="false" datasource="..." runat="server"/>

    You can also turn ViewState off at the page level. This is useful when you do not post back from a page at all, as in the following example:
    <% Page MaintainState="false" %>
    Note that this attribute is also supported by the User Control directive. To analyze the amount of view state used by the server controls on your page, enable tracing and look at the View State column of the Control Hierarchy table. For more information about the Trace feature and how to enable it, see the Application-level Trace Logging feature.
  7. Use System.Text.StringBuilder for string concatenation: Web applications often need to perform extensive string manipulation. Although standard string operators work for concatenation, they have a negative impact on performance. Using the System.Text.StringBuilder class to concatenate strings provides better performance, as demonstrated by the following example:
    // Using concatenation operators can sometimes produce// cleaner-looking code, but performance is not as good.String begin_query = "select UPPER(MachineName) As MachineName, "                   + "LOWER(MachineOwner) As MachineOwner, Status, "                   + "StartTime from NET_STRESS WHERE ";String end_query = " AND StartTime > '" + startTime + "' AND StartTime < '" + endTime + "'";String query = begin_query + GetWhereClause("PASSED") + end_query;// Consider replacing with StringBuilder instead:StringBuilder begin_query = new StringBuilder();begin_query.Append("select UPPER(MachineName) As MachineName ");begin_query.Append("LOWER(MachineOwner) As MachineOwner, Status, ");begin_query.Append("StartTime from NET_STRESS WHERE ");StringBuilder end_query = new StringBuilder();end_query.Append(" AND StartTime > '");end_query.Append(startTime);end_query.Append("' AND StartTime < '");end_query.Append(endTime);end_query.Append("'");String query = begin_query.Append(GetWhereClause("PASSED")).Append(end_query).ToString();
    ' Using concatenation operators can sometimes produce' cleaner-looking code, but performance is not as good.Dim begin_query As String = "select UPPER(MachineName) As MachineName, " _                          & "LOWER(MachineOwner) As MachineOwner, Status, " _                          & "StartTime from NET_STRESS WHERE "Dim end_query As String = " AND StartTime > '" & startTime & "' AND StartTime < '" & endTime & "'"Dim query As String = begin_query & GetWhereClause("PASSED") & end_query' Consider replacing with StringBuilder instead:Dim begin_query As New StringBuilderbegin_query.Append("select UPPER(MachineName) As MachineName ")begin_query.Append("LOWER(MachineOwner) As MachineOwner, Status, ")begin_query.Append("StartTime from NET_STRESS WHERE ")Dim end_query As New StringBuilderend_query.Append(" AND StartTime > '")end_query.Append(startTime)end_query.Append("' AND StartTime < '")end_query.Append(endTime)end_query.Append("'")Dim query As String = begin_query.Append(GetWhereClause("PASSED")).Append(end_query).ToString()
    // Using concatenation operators can sometimes produce// cleaner-looking code, but performance is not as good.var begin_query:String = "select UPPER(MachineName) As MachineName, "                   + "LOWER(MachineOwner) As MachineOwner, Status, "                   + "StartTime from NET_STRESS WHERE ";var end_query:String = " AND StartTime > '" + startTime + "' AND StartTime < '" + endTime + "'";var query:String = begin_query + GetWhereClause("PASSED") + end_query;// Consider replacing with StringBuilder instead:var begin_query:StringBuilder = new StringBuilder();begin_query.Append("select UPPER(MachineName) As MachineName ");begin_query.Append("LOWER(MachineOwner) As MachineOwner, Status, ");begin_query.Append("StartTime from NET_STRESS WHERE ");var end_query:StringBuilder = new StringBuilder();end_query.Append(" AND StartTime > '");end_query.Append(startTime);end_query.Append("' AND StartTime < '");end_query.Append(endTime);end_query.Append("'");var query:String = begin_query.Append(GetWhereClause("PASSED")).Append(end_query).ToString();
    C# VB JScript

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: