asp.net.ph

Skip Navigation LinksHome > ASP.NET Applications > ASP.NET Optimization > Developing High-Performance ASP.NET Applications

Developing High-Performance ASP.NET Applications

ASP.NET Web Applications   ASP.NET Optimization


Coding Practices

The following guidelines suggest ways on how to write code that work more efficiently.

Avoid relying on exceptions in your code

Since exceptions cause performance to suffer significantly, you should never use them as a way to control normal program flow. If it is possible to detect in code a condition that would cause an exception, you should do that instead of waiting to catch the exception itself before handling that condition. Common scenarios include checking for null, assigning to a String that will be parsed into a numeric value, or checking for specific values before applying math operations. The following example demonstrates code that could cause an exception, and you to test for a condition that would do the same thing.

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

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

  C# VB

Use early binding in Visual Basic.NET or JScript code

One of the reasons that developers love Visual Basic, VBScript, and JScript is their "typeless" nature. Variables may be created simply by using them and need no explicit type declaration. When assigning from one type to another, conversions are performed automatically as well. This can be a blessing and a curse, since late binding is a very expensive convenience in terms of performance.

The Visual Basic language now supports type-safe programming through the use of a special Option Strict compiler directive. For backward compatibility purposes, ASP.NET does not enable this option by default. For optimal performance, however, it is highly recommended that you enable this option on your pages. To enable Option Strict, include a Strict attribute in the @ Page directive or, for a user control, the @ Control directive. The following example demonstrates setting this attribute and code that would and would not cause a compiler error.

<%@ Page Language = "VB" Strict = "true" %>
<%
   Dim B
   Dim C As String

   ' this will cause a compiler error
   A = "Hello"

   ' this will cause a compiler error
   B = "World"

   ' this will not
   C = "!!!!!!"

   ' but this will...
   C = 0
%>

JScript.NET also supports typeless programming, though it offers no compiler directive to force early binding. A variable is late bound if:

  • It is declared as explicitly as an Object.
  • It is a field of a class with no type declaration.
  • It is a private function/method member with no explicit type declaration AND the type cannot be inferred from its use.

The last distinction is tricky — the JScript.NET compiler will actually optimize if it can figure out the type based on how a variable is used. In the following example, the variable A is early-bound but the variable B is late-bound.

var A;
var B;

A = "Hello";
B = "World";
B = 0;

For the best performance, assign a type to your JScript.NET variables when you declare them. For example, var A : String.

Use the common language runtime’s garbage collector and automatic memory management appropriately

Be careful about using too much memory per request, such as storing large objects or sets of data in memory, because the garbage collector will have to do more work more often. Also, do not keep unnecessary references to objects in your code when you no longer need the object, because the garbage collector cannot free resources if they are still being referenced.

Try to avoid using objects with Finalize methods, since they will entail more work for the garbage collector at a later time. In particular, never free resources in a call to Finalize, because the resource could consume memory until the garbage collector calls its Finalize method. This last problem often ruins performance in Web server environments, since it can be easy to exhaust the availability of a given resource while waiting for Finalize to run.

Port call-intensive COM components to managed code

The .NET Framework provides a remarkably easy way to interoperate with traditional COM components. The benefit is that you can start taking advantage of the new platform while preserving your existing investments. However, there are some circumstances where the performance cost of keeping your old components is greater than the cost to migrate your components to managed code. Every situation is unique, and the best way to decide whether you need to port a component is to run performance measurements against your Web site. In general though, the performance impact of COM interoperability is proportional to the number of function calls made, or data marshaled, from unmanaged to managed code. It is recommended that you investigate porting to managed code any COM component that requires a high volume of calls in order to interact. This will allow you to benefit from the performance gains of the .NET platform. Alternatively, you might consider redesigning your component to require fewer calls or marshal more data during a single call.

Avoid single-threaded apartment (STA) COM components

By default, ASP.NET does not allow STA COM components to run in a page. To run them, you must include the ASPCompat=true attribute in the @ Page directive in the .aspx file. This switches the thread pool used for page execution to an STA thread pool, while also making the HttpContext and other built-in objects available to the COM object. Avoiding STA COM components is a performance optimization because it avoids any call marshaling from multithreaded apartment ( MTA ) to STA threads.

If you must use an STA COM component, avoid making numerous calls during an execution and try to send as much information as possible during each call. Also, avoid creating STA COM components during the construction of the page. For example, in the following code, the SampleSTAComponent would be instantiated at page construction time, which is created from a thread that is not the STA thread that runs the page. This can have an adverse performance impact, since it will require marshaling between MTA and STA threads to construct the page.

<%@ Page Language = "VB" ASPCompat = "true" %>
<script runat=server>
Dim myComp as new SampleSTAComponent ( )
Public Sub Page_Load ( )
   myComp.Name = "Sample"
End Sub
</script>
<html>
<%
   Response.Write ( Server.HtmlEncode(myComp.SayHello ) )
%>
</html>

The preferred mechanism is to delay object creation until the code is executing under an STA thread, as in the following example:

<%@ Page Language = "VB" ASPCompat = "true" %>
<script runat=server>
Dim myComp
Public Sub Page_Load ( )
   myComp = new SampleSTAComponent ( )
   myComp.Name = "Sample"
End Sub
</script>
<html>
<%
   Response.Write ( Server.HtmlEncode(myComp.SayHello ) )
%>
</html>

The recommended practice is to construct COM components and external resources only when needed or in the Page_Load method.

You should never store STA COM components in a shared resource (such as the cache or session state) where they can be accessed by threads other than the one that constructed them. Even if an STA thread makes a call to an STA COM component, only the thread that constructed the STA COM component can service the call, which entails marshaling the call to the creator thread. This marshaling can have significant performance penalties and scalability problems. In such cases, consider making the COM component into an MTA COM component or rewriting the component in managed code.

Use System.Text.StringBuilder for String concatenation

Web applications often need to perform extensive String manipulation and using standard string operators is a very poor performance choice. The StringBuilder class offers higher performance when you want to concatenate strings.

See Also


Back to top


© 2025 Reynald Nuñez and asp.net.ph. All rights reserved.

If you have any question, comment or suggestion
about this site, please send us a note