Click here to Skip to main content
Click here to Skip to main content

How to improve the performance of managed code

, 29 Oct 2013
Rate this:
Please Sign up or sign in to vote.
Summarizes some ideas on how to improve code performance

Introduction

This articles aims to help and inform on how to improve code performance.

Background

The reason this article is being made comes from the help it was given me here at code project to improve some code I was doing. I intend to summarize the ideas based on other articles and if you wish to learn more about them, the reference will be at the end.

Just because you can get more done with less effort is not a license to abdicate your responsibility to code wisely.
  • Design for efficient resource management:

    Quite simple, avoid allocating objects and their resources before you actually need them and make sure they will be released as soon as they are not being used.

  • Reduce boundary crossing:

    Try to reduce the number of method calls that cross remoting boundaries because this introduces marshaling and potentially thread switching overhead

  • Prefer Single Large Assemblies over many small ones:

    If you have many small assemblies loading together, check to see if it is possible to turn them into one. This might reduce over heading on loading metadata, security checks and more.

  • Treat threads as a Shared Resource:

    Creating threads is an expensive operation and may affect scalability. Whenever possible, try to treat them as a shared resource and use the optimized .NET thread pool.

  • Do not make classes threads safe by default:

    Thread control is usually needed at a higher layer in the software architecture rather than individual class level and the incorrect use may cause unnecessary overhead from thread-safety features. Also, thread safe collections have a more complex design to offer those thread-safety services.

  • Consider using a sealed key word:

    Sealing methods makes them candidates for inlining and other compiling optimizations. Just a note, always consider all implication of sealing a method or class.

    public class MainClass
    { 
        protected virtual void Method() 
        { 
        //Some code
        } 
    }

    You can override and seal the method in a derived class.

    public class DerivedClass : MainClass 
    { 
        protected override sealed void Method() 
        {
        //Some code
        } 
    }
  • Consider the Tradeoff of virtual members:

    If you don't need to extend your class, then try to avoid virtual members due to their more expensive calls that can negate certain run-time performance optimizations.

  • Consider using overloaded methods:

    Sensitive methods that takes any number of parameters result in code paths for each possible combination of parameters. If it is possible, change it by a small set of overloaded methods.

    //method taking variable number of arguments
    void DoSomething (params object [] parameters)
    
    //overloaded methods
    void DoSomething (int aParameters, int otherParameters)
    void DoSomething (int aParameters, int otherParameters, int otherOtherParameter)
  • Know the cost of accessing a property:

    Properties that simply get or set a variable without any extra logic perform like a public variable. The following table shows the time needed (in ns) to get and set integer instance fields and properties

    AVG MIN PRIMITIVE
    1.0 1.0 Get Field
    1.2 1.2 Set Field
    1.2 1.2 Get/Set Property
    6.4 6.3 Get/Set virtual Field/Property
    Source: http://msdn.microsoft.com/en-us/library/ms973852.aspx

  • Private vs Public members:

    Public member cause additional overhead when you use the XmlSerializer class.

  • Avoid Calling GC.Collect:

    Whenever you call the GC.Collect method, it will execute the full collection of all group object generations. This is a very expensive operation because all objects must be visited to ensure a complete collection. The garbage collector is designed to be self-tuning and it adjusts its operation as required, but if there is a reason that makes calling it necessary, consider doing the following:

    // This gets rid of the dead objects
    System.GC.Collect(); 
    
    // This ensures that the current thread waits until finalizers for all objects are called.
    System.GC.WaitForPendingFinalizers(); 
    
    // This releases the memory associated with the objects that were just finalized. 
    System.GC.Collect();
  • Prefer Arrays to Collections:

    Arrays are the fastest of all collections, so unless you need special functionality, such as dynamic extension of the collection, you should consider using arrays rather than collections. Arrays also avoid the boxing and unboxing overhead.

  • Consider FOR instead of FOREACH:

    Use for instead of foreach, in C#, to iterate the contents of arrays or collections in performance critical code, it will avoid unecessary overhead, specially if you do not need the protections offered by foreach.

  • Review your code:

    Prioritize your code review process by identifying code paths that are frequently executed and begin your review process in these areas. Even the slightest inefficiency inside a loop is magnified many times over depending on the number of iterations. Specifically watch out for repetitive property access inside your loops, using foreach instead of for, performing expensive operations within your loops, and using recursion. Recursion incurs the overhead of having to repeatedly build new stack frames.

  • Use String builder:

    StringBuilder is efficient for string concatenation where the number and size of appends is unknown.

    //Prefer this 
    StringBuilder example;
    example.Append(str1);
    example.Append(str2);
    example.Append(str3);
    example.Append(str4);
    
    //over this
    sb.Append(str1+str2+str3+str4);
  • Avoid Rethrowing Exceptions:

    Rethrowing exceptions is inefficient. Not only do you pay the cost for the original exception, but you also pay the cost for the exception that you rethrow.

  • Know how to deal with data access

    There are a series of key things which must be considered:

    1. Ensure you close your connections properly to reduce resource pressure.
    2. Make sure that your code uses the correct data provider.
    3. When a stored procedure doesn't return a value, use "ExecuteNonQuery" for optimum performance.
    4. When accessing wide rows or rows with BLOB data, consider the use of "CommandBehavior.SequentialAccess" with "GetBytes" to access BLOB in chunks.
    5. Returning large amounts of data increases query time and the time it takes to transfer the data across the network
  • Boxing and Unboxing Overhead:

    The act of boxing causes both a operations of heap allocation and a memory copy. Avoid passing value types in method parameters that expect a reference type. Where boxing is unavoidable, to reduce the boxing overhead, box your variable once and keep an object reference to the boxed copy as long as needed, and then unbox it when you need a value type again.

    int num = 123;
    object boxedNum;
    
    // Explicit boxing. In doing so, use the boxedNum variable instead of num
    box = (object)num;

Source

MSDN Library for all hyperlinks and http://msdn.microsoft.com/pt-br/library/ms998547.aspx for the description and definitions that I summarized here. I reccomend the reading for everyone. It is far more detailed and contains way more examples.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

About the Author

Paulo Augusto Künzel
Software Developer
Brazil Brazil
I work as a software developer for a multinational company and at the moment the focus lies on developing reports. Also, I am studying the equivalent to an Associate degree in System's Development and Analysis because after finishing my H.N.C. Business I was bitten by the programming bug. After that my passion for computer science has only increased.

Comments and Discussions

 
GeneralMy vote of 5 PingroupMember 322382729-Oct-13 3:00 
GeneralMy vote of 4 Pinmembercjb1109-Oct-13 20:44 
Would be even better if it showed before/after examples.
GeneralRe: My vote of 4 PinprofessionalPaulo Kunzel10-Oct-13 3:46 
GeneralRe: My vote of 4 PinmvpFlorian Rappl28-Oct-13 8:15 
GeneralRe: My vote of 4 [modified] PinprofessionalPaulo Augusto Künzel29-Oct-13 3:01 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web01 | 2.8.140721.1 | Last Updated 29 Oct 2013
Article Copyright 2013 by Paulo Augusto Künzel
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid