posted on Friday, October 08, 2004 10:41 AM
by
davidboschmans
Code Review with a focus on Performance: Part 3
This is the last part of a 3-part posts I am writing on reviewing code with a focus on performance. [Part 1, Part 2]
Of course, as I said earlier, one can think of many other performance improvement tips and tricks. However these performance code review rules should be a good place to start!
1. Tracing using WriteIf or WriteLineIf [C# / VB.NET]
Calling WriteIf or WriteLineIf on either the Debug or Trace .NET Framework classes when the condition is false causes unnecessary code to be executed.
To increase performance wrap a Write or WriteLine method in an If statement. Performance is improved because it is not necessary to execute the entire WriteIf or WriteLineIf statement.
Change WriteIf and WriteLineIf statements to Write and WriteLine statements, respectively, wrapped with an If statement.
[C#]
Use:
If(condition)
{
Trace.Write("error!");
}
instead of:
Trace.WriteIf(condition, "error!");
2. Implement some form of caching on page [HTML]
If a page has any static content or content that does not change often, consider using one of several caching methods to improve response time.
There are several methods of caching available. Research which method is right for your application.
3. Capturing entire Request collection found [C# / VB.NET]
For performance reasons, the technique of capturing all the Request collection contents is not generally recommended.
Capture the individual Request properties needed in the application.
4. Change Response.Redirect to Server.Transfer [C# / VB.NET]
The Response.Redirect function instructs the browser to request a different page. It is often used to redirect the user to a logon or to an error page, which forces a new page request. As a result, the browser must make two round trips to the Web server, and the Web server must handle an extra request.
In IIS 5.0 Server.Transfer transfers execution to a different ASP page on the same server. This feature eliminates the extra browser-to-Web-server round trip. The benefits are optimized system performance and enhanced response time for the user.
Replace the Response.Redirect command with the Server.Transfer command.
Updated Via Darrell Norton: Note this security issue with "Server.Transfer".
5. UBound() or LBound() statement found [VB.NET]
UBound() and LBound() are expensive operations from a performance perspective. Therefore, if you are evaluating the upperbound or lowerbound of this array anywhere else in the procedure and its upper bound and/or lower bound is not being redimensioned, it is recommended that you use a variable to store the UBound() or LBound().
As an alternative, assign a variable to hold the value of this function, if it is used more than once. A better fix is to use the built in GetUpperBound() or GetLowerBound() methods available in the .NET framework.
6. Use of AspCompat page attribute may degrade page performance [HTML]
When the AspCompat attribute is set to true, the page is allowed to be executed on a single-threaded apartment (STA) thread. This allows the page to call single-threaded components, such as a component developed with Microsoft Visual Basic 6.0. Setting this attribute to true, however, may cause a degradation in your page's performance.
Remove the attribute AspCompat="true" from the Page declaration, if possible in your application.
7. No validation controls found on Web Form [HTML]
Avoid round trips to the server for validation of data when possible. Validation controls facilitate performing validation on the client side.
Consider adding validation controls to the Web Form.
8. View state on pages not required on Web User Control [HTML]
View state is enabled by default. The overhead of additional data required to maintain the view state should be avoided when the page will not be posted back to itself.
Add the EnableViewState="false" attribute to the Page directive. Alternatively, set the EnableViewState property on individual controls that do not need their view state preserved.
9. Avoid creating unsealed Attributes [C# / VB.NET]
A public type inherits from System.Attribute, is not abstract, and is not sealed (NotInheritable in Visual Basic).
The .NET Framework class library provides methods for retrieving custom attributes. These methods search the attribute inheritance hierarchy by default; for example System.Attribute.GetCustomAttribute searches for the specified attribute type, or any attribute type that extends the specified attribute type. Sealing the attribute eliminates the search through the inheritance hierarchy, and can improve performance.
To fix this, seal the attribute type or make it abstract.
The following example shows a custom attribute that satisfies this rule.
[VB.NET]
Imports System
Namespace PerformanceLib
' Satisfies FxCop rule: AvoidUnsealedAttributes.
<AttributeUsage(AttributeTargets.Class Or AttributeTargets.Struct)> _
NotInheritable Public Class DeveloperAttribute
Inherits Attribute
Private nameValue As String
Public Sub New(name As String)
nameValue = name
End Sub
Public ReadOnly Property Name() As String
Get
Return nameValue
End Get
End Property
End Class
End Namespace
[C#]
using System;
namespace PerformanceLib
{
// Satisfies FxCop rule: AvoidUnsealedAttributes.
[AttributeUsage(AttributeTargets.Class|AttributeTargets.Struct)]
public sealed class DeveloperAttribute: Attribute
{
private string nameValue;
public DeveloperAttribute(string name)
{
nameValue = name;
}
public string Name
{
get
{
return nameValue;
}
}
}
}
10. Consider overriding Equals and the equality operator on value types [C# / VB.NET]
A public value type does not override System.Object.Equals, or does not implement the equality operator (==). This rule does not check enumerations.
For value types, the inherited implementation of Object.Equals uses the Reflection library, and compares the contents of all fields. Reflection is computationally expensive, and comparing every field for equality might be unnecessary. If you expect users to compare or sort instances, or use them as hash table keys, your value type should implement Object.Equals. If your programming language supports operator overloading, you should also provide an implementation of the equality and inequality operators.
To fix a violation of this rule, provide an implementation of Object.Equals. If possible, implement the equality operator.
11. Throwing exceptions in destructors [C# / VB.NET]
Throwing exceptions in destructors (Finalizers for Visual Basic .NET) affects performance as well as could cause logic problems when shutting down a class. Destructor must run as fast as possible because they execute in their own thread while all other threads of your application are blocked. Throwing an exception is an expensive operation. One issue is that since all other application threads must wait for the exception to finish, the application may experience periods of slow response. Another larger issue is with the logic of your application. Throwing an error in a destructor may cause unwanted side effects.
Do not throw exceptions in destructors.
12. Slow ADO.NET collection element addressing [C# / VB.NET]
Using a string literal to reference columns in an ADO.NET DataTable is one of the slowest methods for accessing data in a DataSet. The fastest method to access data in an ADO.NET DataRow is to use a DataColumn type as the index parameter. An alternate method is to use a constant or enum value.
Change the column indexer to use one of the previously mentioned data types.