Test loops at the top or bottom? (while vs. do whi

2020-02-16 03:12发布

When I was taking CS in college (mid 80's), one of the ideas that was constantly repeated was to always write loops which test at the top (while...) rather than at the bottom (do ... while) of the loop. These notions were often backed up with references to studies which showed that loops which tested at the top were statistically much more likely to be correct than their bottom-testing counterparts.

As a result, I almost always write loops which test at the top. I don't do it if it introduces extra complexity in the code, but that case seems rare. I notice that some programmers tend to almost exclusively write loops that test at the bottom. When I see constructs like:

if (condition)
{
    do
    {
       ...
    } while (same condition);
}

or the inverse (if inside the while), it makes me wonder if they actually wrote it that way or if they added the if statement when they realized the loop didn't handle the null case.

I've done some googling, but haven't been able to find any literature on this subject. How do you guys (and gals) write your loops?

30条回答
手持菜刀,她持情操
2楼-- · 2020-02-16 04:06

From my limited knowledge of code generation I think it may be a good idea to write bottom test loops since they enable the compiler to perform loop optimizations better. For bottom test loops it is guaranteed that the loop executes at least once. This means loop invariant code "dominates" the exit node. And thus can be safely moved just before the loop starts.

查看更多
萌系小妹纸
3楼-- · 2020-02-16 04:07

For the sake of readability it seems sensible to test at the top. The fact it is a loop is important; the person reading the code should be aware of the loop conditions before trying to comprehend the body of the loop.

查看更多
We Are One
4楼-- · 2020-02-16 04:08

I guess some people test at the bottom because you could save one or a few machine cycles by doing that 30 years ago.

查看更多
forever°为你锁心
5楼-- · 2020-02-16 04:11

Here's a good real-world example I came across recently. Suppose you have a number of processing tasks (like processing elements in an array) and you wish to split the work between one thread per CPU core present. There must be at least one core to be running the current code! So you can use a do... while something like:

do {
    get_tasks_for_core();
    launch_thread();
} while (cores_remaining());

It's almost negligable, but it might be worth considering the performance benefit: it could equally be written as a standard while loop, but that would always make an unnecessary initial comparison that would always evaluate true - and on single-core, the do-while condition branches more predictably (always false, versus alternating true/false for a standard while).

查看更多
叛逆
6楼-- · 2020-02-16 04:11

A while() checks the condition before each execution of the loop body and a do...while() checks the condition after each execution of the loop body.

Thus, **do...while()**s will always execute the loop body at least once.

Functionally, a while() is equivalent to

startOfLoop:
    if (!condition)
        goto endOfLoop;

    //loop body goes here

    goto startOfLoop;
endOfLoop:

and a do...while() is equivalent to

startOfLoop:

    //loop body

    //goes here
    if (condition)
        goto startOfLoop;

Note that the implementation is probably more efficient than this. However, a do...while() does involve one less comparison than a while() so it is slightly faster. Use a do...while() if:

  • you know that the condition will always be true the first time around, or
  • you want the loop to execute once even if the condition is false to begin with.
查看更多
劫难
7楼-- · 2020-02-16 04:11

I tend to prefer do-while loops, myself. If the condition will always be true at the start of the loop, I prefer to test it at the end. To my eye, the whole point of testing conditions (other than assertions) is that one doesn't know the result of the test. If I see a while loop with the condition test at the top, my inclination is to consider the case that the loop executes zero times. If that can never happen, why not code in a way that clearly shows that?

查看更多
登录 后发表回答