.NET Framework 2.0 Performance Inspection Questions - Looping and Recursion

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Srinath Vasireddy, Ashish Babbar, Rico Mariani, and Alex Mackman


Contents

Looping and Recursion Inefficiencies

Inefficient looping and recursion can create many bottlenecks. Also, any slight inefficiency is magnified due to it being repeatedly executed. For this reason, you should take extra care to ensure the code within the loop or the recursive method is optimized. For more information about the questions and issues raised in this section, see .NET 2.0 Performance Guidelines - Iterating and Looping. Use the following review questions to help identify performance issues in your loops:

  • Do you repetitively access properties?
  • Do you use recursion?
  • Do you use foreach?
  • Do you perform expensive operations within your loops?


Do You Repetitively Access Properties?

Repeated accessing of object properties can be expensive. Properties can appear to be simple, but might in fact involve expensive processing operations.


Do You Use Recursion?

If your code uses recursion, consider using a loop instead. A loop is preferable in some scenarios because each recursive call builds a new stack frame for the call. This results in consumption of memory, which can be expensive depending upon the number of recursions. A loop does not require any stack frame creation unless there is a method call inside the loop.

If you do use recursion, check that your code establishes a maximum number of times it can recurse, and ensure there is always a way out of the recursion and that there is no danger of running out of stack space.


Do You Use foreach?

Using foreach can result in extra overhead because of the way enumeration is implemented in .NET Framework collections. .NET Framework 1.1 collections provide an enumerator for the foreach statement to use by overriding the IEnumerable.GetEnumerator. This approach is suboptimal because it introduces both managed heap and virtual function overhead associated with foreach on simple collection types. This can be a significant factor in performance-sensitive regions of your application. If you are developing a custom collection for your custom type, consider the following guidelines while implementing IEnumerable:

If you implement IEnumerable.GetEnumerator, also implement a nonvirtual GetEnumerator method. Your class's IEnumerable.GetEnumerator method should call this nonvirtual method, which should return a nested public enumerator struct. Explicitly implement the IEnumerator.Current property on your enumerator struct.


For more information about implementing custom collections and about how to implement IEnumerable as efficiently as possible, see .NET 2.0 Performance Guidelines - Collections.

Consider using a for loop instead of foreach to increase performance for iterating through .NET Framework collections that can be indexed with an integer.


Do You Perform Expensive Operations Within Your Loops?

Examine the code in your loop and look for the following opportunities for optimization:

  • Move any code out of the loop that does not change in the loop.
  • Investigate the methods called inside the loop. If the called methods contain small amounts of code, consider inlining them or parts of them.
  • If the code in the loop performs string concatenation, make sure that it uses StringBuilder.
  • If you test for multiple exit conditions, begin the expression with the one most likely to allow you to exit.
  • Do not use exceptions as a tool to exit one or more loops.
  • Avoid calling properties within loops and if you can, check what the property accessor does. Calling a property can be a very expensive operation if the property is performing complex operations.
Personal tools