Skip to main content
9 of 9
added 23 characters in body
jgmjgm
  • 149
  • 4

There's nothing inherently wrong or necessarily even bad about nested loops. They do however have certain considerations and pitfalls.

The articles you were led to, likely in the name of brevity or due to a psychological process known as being burnt, skipping over the specifics.

Being burnt is when you have a negative experience of something with the implicating being you then avoid it. For example I might cut vegetables with a sharp knife and cut myself. I might then say sharp knives are bad don't use them to cut vegetables to try to make it impossible for that bad experience to ever happen again. That's obviously very impractical. In reality you just need to be careful. If you're telling someone else to cut vegetables then you have an even stronger sense of this. If I were instructing children to cut vegetables I would very strongly feel to tell them to not use a sharp knife especially if I can't supervise them closely.

The problem is in programming is that you'll not meet peak efficiency if you always prefer safety first. In this case the kids can only cut soft vegetables. Confronted with anything else and they're only going to make a mess of it using a blunt knife. It's important to learn the proper use of loops including nested loops and you can't do that if they're deemed bad and you never try to use them.

As many answers here point out a nested for loop is an indication of the performance characteristics of your program which may get exponentially worse each nesting. That is, O(n), O(n^2), O(n^3) and so on which comprises O(n^depth) where depth represents how many loops you have nested. As your nesting grows, the time required grows exponentially. The problem is with this is that it's not a certainty either that your time or space complexity will be that (quite often a * b * c but not all nest loops may run all the time either) nor is it a certainty that you'll have a performance problem even if it is that.

For many people, particularly students, writers and lecturers who to be frank, rarely program for a living or on a day to day basis for loops may also be something they're not used to and that induced too much cognitive load on early encounters. This is a problematic aspect because there's always a learning curve and avoiding it wont be effective in converting students into programmers.

Nested loops can go wild, that is they can end up nested very deeply. If I go through each continent, then through each country, then through each city, then through each shop, then through each shelf, then through each product if it's a can of beans through each bean and measure it's size to get the average then you can see that'll nest very deeply. You'll have a pyramid and a lot of wasted space away from the left margin. You may even end up going off the page.

This is a problem that would be more significant historically where screens were small and of low resolution. In those cases even a few levels of nesting could genuinely take up a lot of space. This is a lesser concern today where the threshold is higher though it can still present a problem if there's enough nesting.

Related is the aesthetics argument. Many people do not find nested for loops aesthetically pleasing in contrast to layouts with more consistent alignment this may or may not be linked to what people are used to, eye tracking and other concerns. It is however problematic in that it tends to be self reinforcing and may ultimately make code harder to read as breaking up a block of code and encapsulating loops behind abstractions such as functions also risks breaking up the mapping of the code to the flow of execution.

There's a natural tendency towards what people are used to. If you're programming something in the simplest way the probability of needing no nesting is highest, the probability of needing one level drops off by an order of magnitude, the probability for another level drops off again. The frequency dropping and essentially meaning the deeper the nesting the less trained the human senses are to anticipate it.

Related to that is that in any complex construct, which a nested loop can be considered, then you should always ask is that the simplest possible solution as there's potential for a missed solution needing less loops. The irony is that a nested solution often is the simplest way to produce something that works with the minimum amount of effort, complexity and cognitive load. It's often natural to nest for loops. If you consider for example one of the answers above where the much faster way than a nested for loop is also far more complex and consists of significantly more code.

A great deal of care is needed as it's often possible to abstract loops away or flatten them yet with the end result ultimately being a cure worse than the disease particularly if you're not for example receiving a measurable and significant performance enhancement from the effort.

It's very common for people to frequently experience performance problems in association to loops which are telling the computer to repeat an action many times and will inherently often be implicated in performance bottlenecks. Unfortunately responses to this can be very superficial. It becomes common for people to see a loop and see a performance problem where there is none and then hide the loop from sight to no real effect. The code "looks" fast but put it on the road, key in the ignition, floor the accelerator and take a look at the speedometer and you might find it's still about as fast as an old lady walking her zimmer frame.

This kind of hiding is similar to if you have ten muggers on your route. If instead of having a straight route to where you want to go you arrange it so that there's a mugger behind every corner then it gives the illusion as you start your journey that there are no muggers. Out of sight out of mind. you're still going to get mugged ten times but now you wont see it coming.

The answer to you're question is that it's both, but neither concerns is absolute. They're either entirely subjective or only contextually objective. Unfortunately sometimes the entirely subjective or rather opinion takes precedent and dominates.

As a rule of thumb, if it needs a nested loop or that seems like the next obvious step, it's best not to deliberate and simply do it. However if any doubts linger then it should be later reviewed.

Another rule of thumb is that you should always check the cardinality and ask yourself is this loop going to be a problem. In my previous example I went through cities. For testing I might only go through ten cities but what's a reasonable maximum number of cities to expect in real world usage? I then might multiply that by the same for continents. It's a rule of thumb to always consider with loops especially that iterate a dynamic (variable) amount of times what that might translate to down the line.

Regardless always do what works first. The way when you do see an opportunity for optimisation your can compare your optimised solution against the easiest to get working and confirm that it yielded the benefits expected. You can also spend too long prematurely optimising before the measurements are in and that leads to YAGNI or a lot of wasted time and missed deadlines.

jgmjgm
  • 149
  • 4