【问题标题】:Who executes faster - for or while loop [closed]谁执行得更快 - for 或 while 循环 [关闭]
【发布时间】:2012-03-10 04:42:08
【问题描述】:

所以基本上我想知道,在 C++ 语言的这些循环中,谁的速度更快? 基本上,这些示例中哪个编译速度更快 -

int S = 1, D = 2, d = 1;
for(int x = 0; x < 10000; x++) {
  S += D/2-d *s;
}

int S = 1, D = 2, d = 1, x = 0;
while(x < 10000) {
  x++;
  S += D/2-d * S;
}

【问题讨论】:

  • (1)“编译会更快”吗?你的意思是“跑得更快”? (2)让编译器做微优化,你应该做更具可读性的事情。可读性适用于程序员,优化适用于编译器
  • 循环的开销真的很重要吗?如果确实如此,那么必须提供更多。您在哪个架构上运行,哪个编译器以及编译器的哪些优化设置?理论上 for 循环可以完全删除,while 可以替换为 x = 10000;
  • 好吧,基本上,我跑得并不快 :),抱歉。
  • @DavidRodríguez-dribeas:天哪……我的评论只出现了几秒钟!

标签: c++


【解决方案1】:

第二个示例的编译速度可能会稍快一些,因为它有 76 个字符长,而第一个示例有 77 个字符,并且它使用不太复杂的语言结构(不太复杂,我的意思是解析起来不太复杂)。

【讨论】:

  • 虽然我承认您是唯一一个解决“哪个编译更快?”这个问题的人。我怀疑lexical analysis 是生成机器代码的编译器的瓶颈...
  • @amit 已在其他答案中解决:代码可能完全相同(尽管只有编译器真正知道,我们只能做出有根据的猜测)
  • 有点荒谬的答案,不是吗?编译成本可能更多地受编译器中不同代码路径的影响,而不是受要解析的单个额外字符的影响。
  • @DavidRodríguez-dribeas 荒谬的问题值得荒谬的答案
  • 在尝试使其看起来合理之前,答案会更好
【解决方案2】:

使用任何半体面的编译器,它都应该编译成完全相同的代码。其实是这样的:

for (begin; cond; loop) {
    block;
}

在语义上等价于(将continueloop 排除在外,正如塞思卡内基在下面建议的那样):

{
    begin;

    while (cond) {
         block;
         loop;
    }
}

【讨论】:

  • 可能不是完全相同相同的代码,for循环中的x++将在更改S之后,不是吗?
  • @amit:由于x++ 没有在表达式S += D/2-d * S 中使用,也没有副作用,所以编译器可以任意切换这两个表达式。所以没有定义顺序:)
  • 这两者并不完全等价(continue 和其他一些东西)
  • @SethCarnegie:即使那样它们也是等价的。
  • @nightcracker no,因为如果你在while 循环中continueloop 表达式将不会运行
【解决方案3】:

编译时间和执行时间是有区别的。对于执行时间,现在的编译器很可能会生成相同的代码。编译时间......很可能也一样。

请注意,您的示例不正确。这两个循环是不等价的。增量首先在while 循环中执行。 for 循环的等价物是:

while(x < 10000) {
  S += D/2-d * S;
  x++;
}

【讨论】:

  • 它们是完全等价的,除非x 的值对S 有一些我不知道的神奇影响?
  • @LightnessRacesinOrbit 哦,你是说在这种情况下,没关系。无法从讽刺中看出,但是是的,你是对的。
  • 我的评论完全没有讽刺意味。移动语句x++不会改变程序的含义,因此两个程序变体是等价的。
  • @LightnessRacesinOrbit 我知道,但是 - “除非 x 的值对 S 有一些我不知道的神奇影响?”
  • @LightnessRacesinOrbit 很俏皮,是吗? (是的,我确实查过轻率的定义):)
【解决方案4】:

唯一能回答这个问题的“人”是剖析师。

在更理论的层面上,编译器会将它们降低到相同的低级构造,如果事实上某些编译器在生成 IR 之前将 for 循环转换为 while 循环。

【讨论】:

  • 如果觉得有必要,它甚至可以展开循环!
  • 或者由于循环是确定的,它可以只计算结果并将变量初始化为它们在循环结束时的值并完全删除循环。
【解决方案5】:

在我的电脑上,这段代码给出了 4 毫秒(小于 0.1%)的平均差异。而且不管哪个函数先执行,a() 还是 b(),第一个比较慢,所以我认为原因在于调度程序的工作原理。

#include <iostream>
#include  <QTime>

const long cycles = 1000000000;

void a()    {
    long s = 0;
    for(long x = 0; x < cycles; x++) {
        s++;
    }
}

void b()   {
    long x = 0;
    long s= 0;
    while(x < cycles) {
        x++;
        s++;
    }
}

int main(int argc, char *argv[])
{        
    QTime t1;
    t1.start();

    b();

    int i1 = t1.elapsed();
    t1.restart();

    a();

    int i2 = t1.elapsed();

    std::cout << i1 <<"\n"<< i2 <<"\n---\n";
    return 0;
}

【讨论】:

    最近更新 更多