17

I've written some code that has some fairly deep nests (one time, I wrote something that was a conditional check inside a forloop inside a conditional check inside a forloop inside a forloop).

Is there a general guideline on limits to the number of nested for loops/conditionals you have?

4
  • 17
    The guideline is this: "if you worry about reaching the maximum of nesting loops and conditionals, you have way too many" :)
    – Andres F.
    Commented Oct 9, 2013 at 18:14
  • 1
    aw wow. a lot of really good answers. I can't upvote any of them because not enough rep, but thanks a lot for all the feedback !!! I'll give them all a bit of thought and pick an "accepted" answer or whatever. Thanks again for the feedback.
    – Josh Brown
    Commented Oct 9, 2013 at 18:32
  • 1
    It really depends what you are doing. If you are writting Javascript you want it to be as easymode as possible because it needs to execute quickly. If you are using a language like c# or java you can get away with a lot more because the processing power these days is really cheap. THAT SAID I would avoid nesting anything unless you had to. Examples of having to would be for sorting algarithms and search algarithms. Nesting anything can get nasty quickly and is taxing for no reason a lot of times. Just a result of inexperience usually. I would say look for a better method,if not then go w/it Commented Oct 9, 2013 at 19:12
  • 1
    7! If there are more then 7... well lets just say bad things happen if there are more than 7...
    – user69037
    Commented Oct 9, 2013 at 23:41

6 Answers 6

16

You are touching upon one of the classic code metrics - cyclomatic complexity. It doesn't measure nested levels, but rather loops and conditionals (which typically enclose nested levels).

PMD (a Java static analysis tool) has complexity as one of its measures and has this to say about it:

Complexity is determined by the number of decision points in a method plus one for the method entry. The decision points are 'if', 'while', 'for', and 'case labels'. Generally, 1-4 is low complexity, 5-7 indicates moderate complexity, 8-10 is high complexity, and 11+ is very high complexity.

See also Experiments correlating code metrics to bug density from P.SE which goes deeper into the actual measures.

1
  • 1
    I accepted your answer because it seems to give some really good sources as well as advice (which is also inline with other answers on here. would also upvote but not enough rep yet.) Thanks!!!
    – Josh Brown
    Commented Oct 9, 2013 at 18:45
9

The C language allows for up to 127 levels of nested blocks; like 640KB of RAM, that's all anyone should ever need.

In practice, if you find yourself nesting more than 4 or 5 levels deep, think about factoring some of those inner levels out to their own functions (or re-think your algorithm). If nothing else, the code will be easier to scan.

1
  • Not "allows for", but "guarantees to accept". Commented Jun 14, 2017 at 10:10
9

I strongly recommend you to read "Clean Code" by Robert Martin, an extract of which says about nested structures:

Blocks and Indenting

...the blocks within if statements, else statements, while statements, and so on should be one line long. Probably that line should be a function call. Not only does this keep the enclosing function small, but it also adds documentary value because the function called within the block can have a nicely descriptive name.

This also implies that functions should not be large enough to hold nested structures. Therefore, the indent level of a function should not be greater than one or two. This, of course, makes the functions easier to read and understand.

So Bob Martin's recommendation is that the dept of nested structured should be two at most.

I agree with that and, although I don't always comply with it, at least I try.

Also, according with static analisys tool PDM's default configuration, the cyclomatic complexity of a function should not exceed 11, which is easily reached if you go beyond a dept of two.

1
  • 2
    very awesome! Thanks for the pointers! I'll have to grap a copy of that book.
    – Josh Brown
    Commented Oct 9, 2013 at 20:41
5

As with most questions about coding standards, the answer is: Whatever makes your code more readable.

I would argue that's usually fairly close to zero embedded layers of logic. But sometimes it isn't, and sticking vehemently to rules against common sense is more damaging than keeping to the simple policy of reading your own code, or getting someone else to.

Anything that makes it more readable, do it.

2

I personally try to avoid more than four or five levels deep in a single function. More than that would be a bad "code smell". I would suggest try to avoid that by adjusting the structure of the program or re-formulating your problem.

1
  • 3
    without an explanation, this answer may become useless in case if someone else posts an opposite opinion. For example, if someone posts a claim like 'I never worry to have over four or five levels deep in a single function. This is not a kind of bad "code smell".', how would this answer help reader to pick of two opposing opinions? Consider editing it into a better shape
    – gnat
    Commented Oct 10, 2013 at 6:26
2

One downside to nested loops not mentioned yet: If each loop iterates over a large dataset, your algorithm will have high complexity classes. For example,

foreach(foo in foos) {
  foreach(bar in bars) {
    foreach(baz in bazzes) {
      foreach(buzz in buzzes) {
        do_a_thing(foo, bar, baz, buzz);
      }
    }
  }
}

Will run in roughly O(n^4) time if foos, bars, bazzes and buzzes are all about the same size.

This isn't an issue if the collections are always going to be small. Then, everyone else's advice applies. If your collections have a decent chance of being 1000's of items large or larger, though, it would be worth looking for a faster algorithm if possible.

Not the answer you're looking for? Browse other questions tagged or ask your own question.