Friday, January 30, 2015

C# – Best Practices For Writing High Performance Code

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 :
  1. 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
  2. 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.
  3. 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.
  4. 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.
  5. 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
    }
  6. 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.
  7. < 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.
  8. 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.
  9. 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.
  10. 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 here
    Avoid 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