Wednesday, February 17, 2010

Improving performance in Asp.net applications

The following are the some of the guidelines to create a good ASP.NET application.

State Management
1)Disable session when not using it. This can be done at the application level in the "machine.config" file or at a page level. ASP.NET uses a built-in session state mechanism as well as supports your Custom Session State model. However, the cost of Session storage becomes heavy when the users, objects stored increase significantly. Turn off Session State for pages which dont require Session. Typically in a web application there may be static as well as dynamic pages. In the static pages, which dont require Session, the Session State can be turned off. Wherever, you just require Session Data as ReadOnly (where you wont be updating the Session Data), the SessionState can be made ReadOnly.

To turn off Session State at page level,
<%@ Page EnableSessionState="False" %>

To make it ReadOnly at page level,
<%@ Page EnableSessionState="ReadOnly" %>

If your Website has a lot of content pages which are static and only certain pages require Session Data, try considering Turning off SessionState at the Web.Config level and only enable it for those pages which require Session Data. Always the Page settings will override the web.config settings. Session State can be turned off in the web.config as follows:-

<pages enableSessionState="false"></pages>


2)The in-proc model of session management is the fastest of the three options. SQL Server option has the highest performance hit.

3)Minimize the amount and complexity of data stored in a session state. The larger and more complex the data is, the cost of serializing/deserializing of the data is higher (for SQL Server and State server options).

4)Avoid storing STA COM objects in session state.

5)Use the ReadOnly attribute when you can.

6)Use static properties instead of the Application object to store application state.

7)Use application state to share static, read-only data.

8)Do not store single-threaded apartment (STA) COM objects in application state.

9)Turn off View State
View State is the wonderful mechanism which stores the page as well as controls' data, state etc., across round trips. However, the View State can grow heavy significantly increasing the load and hence, View State must be turned off for pages which dont require the same. ViewState can be turned off at page level as follows:-

<%@ Page EnableViewState="False" %>

10)Save server control view state only when necessary.

11)Minimize the number of objects you store in view state.

Server Round Trips
1)Use Server.Transfer for redirecting between pages in the same application. This will avoid unnecessary client-side redirection.

2)Avoid unnecessary round-trips to the server - Code like validating user input can be handled at the client side itself.

3)Use Page.IsPostback to avoid unnecessary processing on a round trip.

Use of Server Controls
1)Use server controls in appropriate circumstances. Even though are they are very easy to implement, they are expensive because they are server resources. Sometimes, it is easier to use simple rendering or data-binding.

2)Avoid creating deep hierarchies of controls.

Exception Handling
1)Don't rely on exceptions in the code. Exceptions reduce performance. Do not catch the exception itself before handling the condition.

// Consider changing this...
try { result = 100 / num;}
catch (Exception e) { result = 0;}

// to this...
if (num != 0)
result = 100 / num;
else
result = 0;

2)To guarantee resources are cleaned up when an exception occurs, use a try/finally block. Close the resources in the finally clause. Using a try/finally block ensures that resources are disposed even if an exception occurs. Open your connection just before needing it, and close it as soon as you're done with it. Your motto should always be "get in, get/save data, get out." If you use different objects, make sure you call the Dispose method of the object or the Close method if one is provided. Failing to call Close or Dispose prolongs the life of the object in memory long after the client stops using it. This defers the cleanup and can contribute to memory pressure. Database connection and files are examples of shared resources that should be explicitly closed.

Com Components
1)Port call-intensive COM components to managed code. While doing Interop try avoiding lot of calls. The cost of marshalling the data ranges from relatively cheap (i.e. int, bool) to more expensive (i.e. strings). Strings, a common type of data exchanged for web applications, can be expensive because all strings in the CLR are in Unicode, but COM or native methods may require other types of encoding (i.e. ASCII).

2)Release the COM objects or native resources as soon as the usage is over. This will allow other requests to utilize them, as well as reducing performance issues, such as having the GC release them at a later point.

DataBase Related:
1)Use SQL server stored procedures for data access.

2)Use the SQLDataReader class for a fast forward-only data cursor.

3)Datagrid is a quick way of displaying data, but it slows down the application. The other alternative, which is faster, is rendering the data for simple cases. But this difficult to maintain. A middle of the road solution could be a repeater control, which is light, efficient, customizable and programmable.

4)Cache data and page output whenever possible.

Collections:
1) Avoid the use of ArrayList. Because any objects added into the Arraylist are added as System.Object and when retrieving values back from the arraylist, these objects are to be unboxed to return the actual valuetype. So it is recommended to use the custom typed collections instead of ArrayList. .NET provides a strongly typed collection class for String in System.Collection.Specialized, namely StringCollection. For other type of class, rename the _ClassType attribute in the attached file to your required type.

2) Reconsider the use of Hashtable instead try other dictionary such as StringDictionary, NameValueCollection, HybridCollection. Hashtable can be used if less number of values are stored.

3)Enumerating into collections sometimes is more expensive than index access in a loop. This is because the CLR can sometimes optimize array indexes and bounds checks away in loops, but can't detect them in for each type of code.

Others:
1)Disable debug mode before deploying the application.

2)For applications that rely extensively one external resource, consider enabling web gardening on multiprocessor computers. The ASP.NET process model helps enable scalability by distributing work to several processes, one on each CPU. If the application is using a slow database server or calls COM objects that access external resources, web gardening could be a solution.

3)Do a "pre-batch" compilation. To achieve this, request a page from the site.

4)Setting the AutoEventWireup attribute to false in the Machine.config file means that the page will not match method names to events and hook them up (for example, Page_Load). If page developers want to use these events, they will need to override the methods in the base class (for example, they will need to override Page.OnLoad for the page load event instead of using a Page_Load method). If you disable AutoEventWireup, your pages will get a slight performance boost by leaving the event wiring to the page author instead of performing it automatically.

5)Buffering is on by default. Turning it off will slow down the performance. Don't code for string buffering - Response.Write will automatically buffer any responses without the need for the user to do it. Use multiple Response.Writes rather than create strings via concatenation, especially if concatenating long strings.