Looping
Please avoid if else conditions .Instead use switch statements.
Avoid For-Each for iteration in performance critical code paths, instead use FOR loops.
If you test for multiple exit conditions, begin the expression with the one most likely to allow you to exit.
Avoid calling properties inside within loops.
If the methods called inside the loop contain small amounts of code consider in-lining them or parts of them.
Naming Conventions
The controls should be named with Pascal casing.
The variables should be named with Camel casing.
The functions should be named with Pascal casing.
Always name the variables with proper complete meaningful word, do not use short names.
Always declare constant variables, when the same variable name is used multiple times on the same page.
Please remove all the unused variables from the application.
Conditional check
For Strings check IsNullOrEmpty.
For Integers check > 0.
For DataTable check !=null.
External data, check for the following situations:
Not enough security privileges .
The information is not there.
The information is incomplete.
The information is complete, but invalid.
Saving data, check for the following situations:
Not enough security privileges.
The device isn’t there.
There’s not enough space.
The device has a physical fault.
Exception Handling
Never ever have an empty exception block.
Don’t clear the stack trace when re-throwing an exception
Rethrowing exceptions is inefficient. Not only pay the cost for the original exception, but also pay the cost for the exception that you rethrow.
Rethrowing exceptions also makes it harder to debug code because you cannot see the original location of the thrown exception in the debugger.
The stack trace is one of the most useful information that an exception carries. Often, we need to put some exception handling on catch blocks (e.g., to rollback a transaction) and re-throw the exception.
The wrong way:
try
{
// Some code that throws an exception
}
catch (Exception ex)
{
// some code that handles the exception
throw ex;
}
Why is this wrong? Because, when you examine the stack trace, the point of the exception will be the line of the “throw ex;”, hiding the real error location. Try it.
try
{
// Some code that throws an exception
}
catch (Exception ex)
{
// some code that handles the exception
throw;
}
What has changed? Instead of “throw ex;”, which will throw a new exception and clear the stack trace, we have simply “throw;”. If you don’t specify the exception, the throw statement will simply rethrow the very same exception the catch statement caught. This will keep your stack trace intact, but still allows you to put code in your catch blocks.
Know when to set up a try/catch block. For example, you can programmatically check for a condition that is likely to occur without using exception handling. In other situations, using exception handling to catch an error condition is appropriate.
MEMORY MANAGEMENT
Call Dispose or Close
Check that your code calls Dispose or Close on all classes that support these methods. Common disposable resources include the following:
Database-related classes: Connection, DataReader, and Transaction.
File-based classes: FileStream and BinaryWriter.
Stream-based classes: StreamReader, TextReader, TextWriter, BinaryReader, and TextWriter.
Network-based classes: Socket, UdpClient, and TcpClient.
Also check that your C# code uses the using statement to ensure that Dispose is called. If you have Visual Basic .NET code, make sure it uses a Finally block to ensure that resources are released.
Set member variables to null before long-running calls
Identify potentially long-running method calls. Check that you set any class-level member variables that you do not require after the call to null before making the call. This enables those objects to be garbage collected while the call is executing.
There is no need to explicitly set local variables to null because the just-in-time (JIT) compiler can statically determine that the variable is no longer referenced.
Class Design Considerations
Properties
Properties must be simple and should not contain more code than required for getting/setting and validation of the parameters. Properties can look like inexpensive fields to clients of your class, but they may end up performing expensive operations.
Define Only the Required Variables As Public
Should be careful about which members should be made public because with public members you run the risk of exposing sensitive data that can easily be manipulated. In addition to security concerns, you should also avoid unnecessary public members to prevent any additional serialization overhead when you use the XmlSerializer class, which serializes all public members by default.
Seal Your Classes or Methods
If you do not want anybody to extend your base classes, you should mark them with the sealed keyword. Also, if you derive from a base class that has virtual members and you do not want anybody to extend the functionality of your derived class, consider sealing the virtual members in the derived class. Sealing the virtual methods makes them candidates for inlining and other compiler optimizations.
Always use Convert.ToString(), Convert.ToInt32(), and Convert.ToBoolean while casting.
ASP.NET
SESSIONS
Disable session state when not required. Session state is on by default. If your application does not use session state, disable it in Web.config as follows.
If parts of your application need session state, identify pages that do not use it and disable it for those pages by using the following page level attribute.
<@% EnableSessionState = “false” %>
Minimizing the use of session state increases the performance of application. Pages that do not write to a session and pages that only read session data, consider setting EnableSessionState to ReadOnly.
<%@ Page EnableSessionState=”ReadOnly” . . .%>
This is particularly useful when you use HTML frames. The default setting (due to ReaderWriterLock) serializes the page execution. By setting it to ReadOnly, you prevent blocking and allow more parallelism.
Check for nulls before accessing items in session state.
Can improve performance by checking for null before accessing the item, as shown in the following code.
object item = Session[“myitem”];
if(item==null)
{
// do something else
}
A common pitfall when retrieving data from session state is to not check to see if the data is null before accessing it and then catching the resulting exception. You should avoid this because exceptions are expensive.
Storing complex objects in session state
Avoid storing complex objects in session state, particularly if you use an out-of-process session state store. When using out-of-process session state, objects have to be serialized and deserialized for each request, which decreases performance.
Manage Exceptions Efficientl
Implement an error handler in Global.asax?
Although implementing an error handler in Global.asax does not necessarily increase performance, it helps to identify unexpected exceptions that occur in your application. After you identify the exceptions that occur, take appropriate action to avoid these exceptions.
Use try/finally on disposable resources?
Ensure that disposable resources are released in a finally block to ensure they get cleaned up even in the event of an exception. Failing to dispose of resources is a common problem.
Code should avoid exceptions
Code should attempt to avoid exceptions to improve performance because exceptions incur a significant overhead. Use the following approaches:
Check for null values.
Do not use exceptions to control regular application logic.
Do not catch exceptions you cannot handle and obscure useful diagnostic information.
Use the overloaded Server.Transfer method Server.Transfer(String,bool) instead of Server.Transfer, Response.Redirect, and Response.End to avoid exceptions
View State
Disable view state when it is not required
Evaluate each page to determine if you need view state enabled. View state adds overhead to each request. The overhead includes increased page sizes sent to the client as well as a serialization and deserialization cost. You do not need view state under the following conditions:
The page does not post back to itself; the page is only used for output and does not rely on response processing.
Your page’s server controls do not handle events and you have no dynamic or data-bound property values (or they are set in code on every request).
If you are ignoring old data and repopulating the server control every time the page is refreshed.
Steps to reduce the size of view state?
Evaluate your use of view state for each page. To determine a page’s view state size, you can enable tracing and see each how each control uses it. Disable view state on a control-by-control basis.
Optimize Web Pages
Reduce your page size
Try to keep the page size to a minimum. Large page sizes place increased load on the CPU because of increased processing and a significant increase in network bandwidth utilization, which may lead to network congestion. Both of these factors lead to increased response times for clients. Consider the following guidelines to help reduce page size:
Use script includes (script tags rather than interspersing code with HTML).
Remove redundant white space characters from your HTML.
Disable view state for server controls where it is not needed.
Avoid long control names.
Minimize the use of graphics, and use compressed images.
Consider using cascading style sheets to avoid sending the same formatting directives to the client repeatedly.
Disable buffering
Ensure that you have buffering enabled. Buffering causes the server to buffer the output and send it only after it has finished the processing of the page. If buffering is disabled, the worker process needs to continuously stream responses from all concurrent requests; this can be a significant overhead on memory and the processor, especially when you use the ASP.NET process model.
The buffer attribute should be set to true on the element in your application’s Web.config file.
Avoid Response.Redirect
Search your code for “Response.Redirect” and consider replacing it with Server.Transfer. This does not incur the cost of a new request because it avoids any client-side redirection.
You cannot always simply replace Response.Redirect calls with Server.Transfer calls because Server.Transfer uses a new handler during the handler phase of execution. Response.Redirect generates a second request. If you need different authentication and authorization, caching, or other run-time devices on the target, the two mechanisms are not equivalent. Response.Redirect causes an extra request to be sent to the server. Response.Redirect also makes the URL visible to the user. This may be required in some scenarios where you require the user to bookmark the new location.
Set Explicit and Strict to true
Use Option Strict and Explicit to reduce inadvertent late binding when using Visual Basic .NET.
<%@ Page Language=”VB” Explicit=”true” Strict=”true” %>
Disable debugging
In Web.config file and ensure debug is set to false in the section and check .aspx pages to ensure debug is set to false. If debugging is enabled, the compiler does not generate optimized code and pages are not batch compiled.
Disable tracing
In Web.config file to ensure trace is disabled in the section. Also check .aspx pages to ensure trace is set to false.
Accessing Data From ASPX Pages
Use DataSets when you could be using DataReaders
If you do not need to cache data, exchange data between layers or data bind to a control and only need forward-only, read-only access to data, then use DataReader instead.
Do not use DataBinder.Eval
DataBinder.Eval uses reflection, which affects performance. In most cases DataBinder.Eval is called many times from within a page, so implementing alternative methods provides a good opportunity to improve performance.
Avoid the following approach.
<%# DataBinder.Eval(Container.DataItem,”field1″) %><%# DataBinder.Eval(Container.DataItem,”field2″) %>
Use explicit casting. It offers better performance by avoiding the cost of reflection. Cast the Container.DataItem as a DataRowView if the data source is a DataSet.
<%# ((DataRowView)Container.DataItem)[“field1”] %><%# ((DataRowView)Container.DataItem)[“field2”] %>
Cast the Container.DataItem as a String if the data source is an Array or an ArrayList.
<%# ((String)Container.DataItem)[“field1”] %><%# ((String)Container.DataItem)[“field2”] %>
Data Access
Using connections properly
Keeping too many open connections is a common pitfall. Ensure to close your connections properly to reduce resource pressure. Identify areas in your code where you are using connections and ensure the following guidelines are followed:
Open and close the connection within the method.
Explicitly close connections using a finally or using block.
When using DataReaders, specify CommandBehavior.CloseConnection.
If using Fill or Update with a DataSet, do not explicitly open the connection. The Fill and Update methods automatically open and close the connection.
Pool your database connections
Creating database connections is expensive. Reduce the creation overhead by pooling database connections.
If you are pooling your database connections, make certain that you call Close or Dispose on the connection as soon as you are done with the connection. This ensures that it is promptly returned to the pool.
Set pool size appropriately
It is important to optimize the maximum and minimum levels of the pool size to maximize the performance of application. Setting the maximum levels to values that are too high, may end up creating deadlocks and heavy resource utilization on the database. If you use values that are too low, you run the risk of under utilizing the database and queuing up the requests.
Determine appropriate maximum and minimum values for the pool during performance testing and performance tuning.
Use Commands Efficiently
Execute queries that do not return data
If you do not return values from your stored procedure, use ExecuteNonQuery for optimum performance.
Execute queries that only return a single value
Use Command.ExecuteScaler, which returns the value of the first column of the first row.
DataSets
Serialize DataSets
Inefficient serializing of DataSets is a major performance issue for remote calls. You should avoid sending DataSets (especially when using .NET remoting) and consider alternative means of sending data over the wire, such as arrays or simple collections, where possible.
If you serialize DataSets, make sure you adhere to the following guidelines:
Only return relevant data in the DataSet.
Consider using alias column names to shorter actual column names. This helps reduce the size of the DataSet.
Avoid multiple versions of the data. Call AcceptChanges before serializing a DataSet.
When serializing a DataSet over a Remoting channel, use the DataSetSurrogate class.
Search data which has a primary key column
If you need to search a DataSet using a primary key, create the primary key on the DataTable. This creates an index that the Rows.Find method can use to quickly find the required records. Avoid using DataTable.Select, which does not use indices.
Search data which does not have a primary key
If you need to repetitively search by nonprimary key data, create a DataView with a sort order. This creates an index that can be used to improve search efficiency. This is best suited to repetitive searches as there is some cost to creating the index.
DataSets for XML data?
If you do not pass the schema for the XML data, the DataSet tries to infer the schema at run time. Pass XmlReadMode.IgnoreSchema to the ReadXml method to ensure that schema is not inferred.