With faster processors and memory being almost free programmers are increasingly tempted to program for convenience and not performance. I recently had to write an application where performance was paramount and here are my top ten tips for writing high performance C# code :
- Avoid boxing and unboxing
Boxing/unboxing enables value types to be treated as objects which is stored on the garbage collected heap. Boxing is the packaging of the value type in an instance of the object reference type and unboxing is the extraction of the value type from the reference type. Where possible this should be avoided as it is a major drain on performance.
EG:int i = 999;
object oObj = (object)i; // boxing
…
oObj= 999;
i = (int)oObj; // unboxing - Avoid Finalize
The .NET garbage collector automatically handles the disposable of unused items, using Finalize the explicitly destroy an object requires invoking an instance of the garbage collector which is un-necessary and is a drain on performance. - Read Values From Objects Only Once
Reading values from objects is not as fast as assessing the value of a simple variable. For example, a loop through an array’s contents should not access the array’s Length property on each iteration of the loop, instead copy the Length property to an Integer and then access this value on each iteration.
This applies to any classes you create as well, read all properties into a simple string or integer type if possible and then access that type multiple times. - Use The StringBuilder – Wisely!
Concatenating large strings in a loop is a performance drain and the Stringbuilder’s Append method is much more efficient. However don’t go overboard on this, the Stringbuilder is object requires a lot more memory than a String and it is not efficient for concatenating a small number of times – only use the Stringbuilder if more than four concatenations are required. - Minimize Exceptions
Catching and throwing exceptions is very expensive and should be avoided where possible. Exception blocks should never be used to catch an error caused by attempting to access a null object, instead use an statement to test if the object is null before accessing it:
if (myObj != null)
{
//perform operation
}
else
{
//catch error
} - For Instead of ForEach
ForEach can simplify the code in a For loop but it is a heavy object and is slower than a loop written using For. - < Use Sealed ClassesClasses that do not need to be inherited from should be marked as sealed. Sealed classed remove the inheritance features of a class and allows the .NET framework to make several run-time optimizations.
- Thread PoolingInitializing threads is expensive so if your code uses thread, avail of .NET’s thread pooling:WaitCallback methodTarget = new WaitCallback( myClass.UpdateCache );
ThreadPool.QueueUserWorkItem( methodTarget );When QueueUserWorkItem is called, the method is queued and the
calling thread returns and continues execution. The ThreadPool class uses a thread
from the application’s pool to execute the method passed in the callback as soon as
a thread is available. - Collections
Where possible use arrays instead of collections. Arrays are normally more efficient especially for value types. Also, initialize collections to their required size when possible. - Use Strongly Typed ArraysStrongly typed arrays avoids the type conversion or boxing associated with using object arrays to store types.Object[] array = new Object[10]
arr[0] = 2+3; //boxing occurs hereAvoid the boxing overhead by declaring a strongly typed array:int [] arrIn = new int [10];
arrIn[0] = 2+3;
These are just my tips, please let us know if you have any of your own.
No comments:
Post a Comment