When you define a loop inside another loop, it is called a nested loop. There is an outer loop and an inner loop in it. The execution of inner loops depends upon the condition of the outer loop. If the condition of the outer loop evaluates to true, the inner loop iterates.
To solve many programming problems, programmers use nested loops extensively. They are helpful in some situations, but frequently using nested loops is considered a bad practice, especially when you have better choices.
There are three reasons why nested loops can be bad practice if used inappropriately:
- they decrease the readability of the code
- they can reduce performance
- they make debugging harder.
In this article, you will find out why and when nested loops can be a bad practice and how you can avoid them. Let’s get started!
Why are nested loops considered bad practice?
Here is what a simple nested loop looks like.
static void Main()
{
for(int i = 1; i <= 10; i++) //the OUTER Loop
{
for(int j = 1; j<=i; j++) //the INNER Loop
{
Console.Write("*");
}
Console.Write("\n");
}
}
Output:
Although nested loops are not always bad to use, they are considered bad practices due to the following significant reasons:
- Decreased readability of code – The nested loops make your code hard to read and understand. Many beginners struggle with them and find them hard to evaluate as one loop depends on the other. Sometimes, the code having lots of nested loops is called Spaghetti code.
- Reduced performance – The nested loops slow the program execution while increasing the code complexity and decreasing the maintainability. Their quadratic time complexity is the most significant reason that makes the nested loops less usable.
- Harder debugging – When using nested loops, you increase the chance of making a logical error which is the most difficult to trace and resolve. Hence the nested loops make your code hard to debug.
Besides all the drawbacks, there are some situations where you cannot avoid the nested loops, such as working with multidimensional arrays and lists or implementing complex algorithms.
However, there is always an efficient and better alternative to everything in programming.
That doesn’t mean you should immediately go to your code and delete all nested loops. But you need to be aware of the downsides.
What should be the maximum recommended nesting for the loop?
In my experience, you should not nest more than 3 loops as it reduces code readability and makes it less understandable. When there is much nesting, it becomes difficult to track down what a loop is doing.
What is cyclomatic complexity?
Cyclomatic complexity is a measure that determines the level of code complexity. It is the quantitative measure of independent paths in your code by counting the number of decisions. The higher the count, the more complex your code is.
Let’s take a look at one code example:
public int Add(int number_1, int number_2)
{
return number_1 + number_2;
}
The cyclomatic complexity of the above code is 1 as there is only one linearly independent path. Since the article focuses on nested loops, let’s calculate the cyclomatic complexity of the following nested loop:
for (int i = 0; i <= 10; i++)
{
for (int j = 0; j <= 10; j++)
{
Console.WriteLine(i + " x " + j + " = " + i * j);
}
Console.ReadKey();
}
The cyclomatic complexity of the nested loop above is 3.
How to eliminate or reduce nested loops?
In some cases, you cannot avoid nesting the loops in any way. However, there are some ways in which you can reduce their use in your code, such as given below:
- Use recursion – You can always use the recursion to avoid using the nested loops. Alternatively, you can transform data into a format that does not require the nested loops to process them. This may not enhance the performance in every case, but it will in certain conditions.
- Use a hash function – You can search data in arrays much faster than linearly searching it using a hash function. The only problem with the Hash function is that it requires additional space and calculations.
- Use Extract Method refactoring – In Visual Studio, you have an option to put a nested loop into a separate method to increase readability and make debugging easier. When facing a logical error, you can trace it down quickly by setting a breakpoint where the method starts. Visual Studio automatically suggests refactoring the code whenever you add a nested loop. If you choose to do it, it automatically creates a new method and moves the inner loop into that method as follows:
Conclusion
This article suggests that the extensive use of nested loops in your code can increase its complexity, and you may end up with “spaghetti code”.
However, not all the nested loops are bad and sometimes necessary. They are just bad in situations when there are better approaches and algorithms available to use instead of nested loops. However, there are specific ways to avoid nested loops, such as using the hash function, recursive algorithms, and extract method refactoring.