难道编译器产生更好的code的DO-whil​​e循环相对于其他类型的循环? [英] Do compilers produce better code for do-while loops versus other types of loops?

查看:179
本文介绍了难道编译器产生更好的code的DO-whil​​e循环相对于其他类型的循环?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有在这意味着 zlib的COM pression库(这是在Chromium项目中许多人使用)评论在C一个do-whil​​e循环产生更好的code对大多数编译器。这里是code的片段地方出现。

There's a comment in the zlib compression library (which is used in the Chromium project among many others) which implies that a do-while loop in C generates "better" code on most compilers. Here is the snippet of code where it appears.

do {
} while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
         *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
         *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
         *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
         scan < strend);
/* The funny "do {}" generates better code on most compilers */

<一个href=\"https://$c$c.google.com/p/chromium/$c$csearch#chromium/src/third_party/zlib/deflate.c&l=1225\">https://$c$c.google.com/p/chromium/$c$csearch#chromium/src/third_party/zlib/deflate.c&l=1225

有什么证据,多数(或任何)编译器会产生更好的(例如更有效)code?

Is there any evidence that most (or any) compilers would generate better (e.g. more efficient) code?

更新: 马克阿德勒,原来作者之一,<一个href=\"http://stackoverflow.com/questions/20172402/do-compilers-produce-better-$c$c-for-do-while-loops-versus-other-types-of-loops?noredirect=1#comment30090750_20172402\">gave在评论有点背景的。

Update: Mark Adler, one of the original authors, gave a bit of context in the comments.

推荐答案

首先:

A 做的,而循环是不一样的,而 -loop或 -loop。

A do-while loop is not the same as a while-loop or a for-loop.


  • ,而循环可能无法运行循环体的。

  • A 做的,而循环总是在循环体至少一次 - 它跳过初始状态检查

  • while and for loops may not run the loop body at all.
  • A do-while loop always runs the loop body at least once - it skips the initial condition check.

所以这是合乎逻辑的区别。这就是说,不是每个人都严格遵守这一点。这是很常见的,而循环,即使它是保证使用,它会一直循环至少一旦。 (尤其是与的foreach循环的语言。)

So that's the logical difference. That said, not everyone strictly adheres to this. It is quite common for while or for loops to be used even when it is guaranteed that it will always loop at least once. (Especially in languages with foreach loops.)

因此​​,为了避免比较苹果和橘子,我会继续假设循环将始终运行至少一次。此外,我就不提了再次循环,因为它们基本上,而有一点语法糖的循环循环计数器。

So to avoid comparing apples and oranges, I'll proceed assuming that the loop will always run at least once. Furthermore, I won't mention for loops again since they are essentially while loops with a bit of syntax sugar for a loop counter.

所以,我会回答这个问题:

So I'll be answering the question:

如果,而循环是保证循环至少一次,有没有从使用任何性能增益做,而循环来代替。

If a while loop is guaranteed to loop at least once, is there any performance gain from using a do-while loop instead.

A 做的,而跳过第一个条件检查。因此,有少了一个分支,一个评估更低的条件。

A do-while skips the first condition check. So there is one less branch and one less condition to evaluate.

如果条件是昂贵的检查,你知道你保证循环至少一次,那么做的,而循环可能会更快。

If the condition is expensive to check, and you know you're guaranteed to loop at least once, then a do-while loop could be faster.

虽然这被认为是一个微观优化充其量,它是一个编译器不能总是这样:特别是当编译器不能证明该循环将始终输入至少一次

And while this is considered a micro-optimization at best, it is one that the compiler can't always do: Specifically when the compiler is unable to prove that the loop will always enter at least once.

在换言之,而循环:

while (condition){
    body
}

有效地与此相同:

Is effectively the same as this:

if (condition){
    do{
        body
    }while (condition);
}

如果你知道你将永远循环至少一次,如果语句是多余的。

If you know that you will always loop at least once, that if-statement is extraneous.

同样在汇编级别,这大致是不同的回路是如何编译:

Likewise at the assembly level, this is roughly how the different loops compile to:

do-whil​​e循环:

start:
    body
    test
    conditional jump to start

while循环:

    test
    conditional jump to end
start:
    body
    test
    conditional jump to start
end:

请注意,该情况已被复制。另一种方法是:

Note that the condition has been duplicated. An alternate approach is:

    unconditional jump to end
start:
    body
end:
    test
    conditional jump to start

...这交易走重复的code额外跳。

... which trades away the duplicate code for an additional jump.

无论哪种方式,它仍然比正常做的更差,而循环。

Either way, it's still worse than a normal do-while loop.

也就是说,编译器可以做他们想要的东西。如果他们能证明该循环总是进入一次,然后它做的工作适合你。

That said, compilers can do what they want. And if they can prove that the loop always enters once, then it has done the work for you.

但事情是在问题的具体例子有点不可思议,因为它有一个空的循环体。由于没有身体,没有逻辑之间的,而做的,而

But things are bit weird for the particular example in the question because it has an empty loop body. Since there is no body, there's no logical difference between while and do-while.

FWIW,我在这个测试的Visual Studio 2012:

FWIW, I tested this in Visual Studio 2012:


  • 随着空体,但它实际上产生相同的code为,而做的,而。所以这部分很可能旧的日子,编译器并没有想象中大的残余。

  • With the empty body, it does actually generate the same code for while and do-while. So that part is likely a remnant of the old days when compilers weren't as great.

但是,随着非空体,VS2012设法避免的条件code的重复,但仍然会产生一个额外的条件跳转。

But with a non-empty body, VS2012 manages to avoid duplication of the condition code, but still generates an extra conditional jump.

所以这是具有讽刺意味的​​是,虽然在问题凸显的例子做的,而循环可能是在一般情况下快,例如本身似乎为何不给在一个现代化的编译器任何好处。

So it's ironic that while the example in the question highlights why a do-while loop could be faster in the general case, the example itself doesn't seem to give any benefit on a modern compiler.

考虑到评论多大了,我们可以在它为什么会事宜只能猜测。这很可能是当时的编译器不能够识别身体是空的。 (或者,如果他们做到了,他们没有使用的信息。)

Considering how old the comment was, we can only guess at why it would matter. It's very possible that the compilers at the time weren't capable of recognizing that the body was empty. (Or if they did, they didn't use the information.)

这篇关于难道编译器产生更好的code的DO-whil​​e循环相对于其他类型的循环?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆