for循环VS while循环编程语言,c ++ / java?

时间:2011-11-24 20:00:51

标签: java c++ c performance

哪种性能更好?这可能与其他编程语言不一致,因此如果它们不同,或者您可以用您对特定语言的知识回答我的问题,请解释。

我将使用c ++作为示例,但我想知道它在java,c或任何其他主流语言中的工作原理。

int x = 0;
 while (x < 10) {
    cout << x << "\n ";
    x++;
  }

VS

for ( int x = 1; x < 10; x++)   
 cout << x << "\n ";

哪一个表现更好?如果它是for循环,那么让我们说已经声明了我们可以在while循环增量中使用的整数,我们不需要为while循环创建它?

示例:

int age = 17; //this was made for something else in the code, not a while loop. But fortunately for us, our while loop just so happened to need the number 17.

 while (age < 25) {
        cout << age << "\n ";
        age++;
      }

这个实例是否会使while循环成为比创建for循环更好的选择?我看到的问题有点类似于此,但我不认为这是重复的,或者其他问题的任何答案都回答了我的问题。

我希望对这个问题有一个解释,解释它是否是编译器特定的,它是如何工作的,或者对这个问题有什么好的答案。

9 个答案:

答案 0 :(得分:4)

所有合理的编译器都应该编译等效的循环到相同的汇编/ IL代码,包括分支和跳转。 (至少启用了优化)

答案 1 :(得分:3)

在某些CPU架构上,循环的特征可能提供比forwhile的选择更多优化的机会。

特别是,FORTRANPascal建议一些CPU可以优化的循环迭代次数的常量(而不是变量)。例如,在Cyber​​(20世纪70年代的铁恐龙主机)上,15位寄存器保存for循环索引,可以轻松进行比较。而while使用一个或两个难以访问的60位寄存器。此外,Cyber​​分支指令比循环管理或可能的循环内容昂贵得多。在这种情况下,高级别的优化可能会展开循环以避免所有开销。

然而,现代代码生成器不像以前那样工作:源代码变成了一个中间解析结构,它抽象出这些选择。简而言之,forwhile没有任何区别。

答案 2 :(得分:2)

我发现很难想象你给出的代码示例会有不同的性能特征。

我确实对你有一种温和的好奇心。在类似Pascal的语言(例如Delphi)中,循环限制仅被评估一次。这与C语言不同,其中每次迭代都会评估循环限制。这可能会对性能产生影响,但当然通过在循环外部引入本地来编写C语言中的高性能代码是微不足道的。

例如:

<强>的Delphi

for i := 0 to List.Count-1 do
  DoStuff(List[i]);

List.Count仅评估一次。

<强> C ++

for (int i=0; i<List.getCount(); i++)
  DoStuff(List.getItem(i));

这里,每次循环都会调用List.getCount()

如果发现评估环路限制很昂贵,那么这种差异可能是相关的。当然,在循环外评估List.getCount()并将结果存储在局部变量中是微不足道的。

比较Pascal和C / C ++的for循环后,我会说Pascal版本相比之下非常简单。这不一定是件坏事,因为对于更复杂的事情,总有while可用。

答案 3 :(得分:2)

您发布的示例实际上对whilefor有不同的行为。

此:

for (int x = 0; x < 100; ++x) {
  foo y;
  y.bar(x);
}

等同于:

{ // extra blocks needed
  int x = 0;
  while (x < 100) {
    {
      foo y;
      y.bar(x);
    }
    ++x;
  }
}

你可以期待性能相​​同。 没有额外的括号,意思不同,因此生成的装配可能会有所不同。

虽然在现代编译器中两者之间的差异是不存在的,但for可以更明确地优化其状态。

答案 4 :(得分:1)

这是特定于编译器的,但我认为在几乎所有情况下,两种方法的性能都是相同的。

为了确定特定情况,你应该测量性能,虽然在你花费很多时间微优化这样的代码之前,你应该首先确定这实际上是你的应用程序的瓶颈(可能不是)

你的第二个例子可以写成for循环而没有初始化表达式。

int age = 17; // This was made for something else in the code

for (; age < 25; age++) {
    cout << age << endl;
}

答案 5 :(得分:1)

我认为编译器现在已经足够优化了,所以如果使用for循环或while循环,它确实没有任何区别。

答案 6 :(得分:1)

我建议你写一个小例子和时间区别。然后选择您发现的最快的解决方案。

答案 7 :(得分:1)

它与编译器优化没有任何区别!

My 2cts,当它涉及循环实现选择时,使用适合算法逻辑的那个是很重要的。阅读代码更容易。

答案 8 :(得分:1)

你提出的问题很糟糕。你在循环中拥有的IO占据了循环处理语句所能添加的所有数量至少一个数量级。我的赌注甚至是你无法测量任何显着的差异,因为它不能与IO产生的噪声(在测量方面)区分开来。

如果循环中的代码真的很快,那么事情才会重要。这里的快速意义甚至没有内存读取指令,从那以后CPU内存带宽将再次占主导地位。

所以,如果你真的好奇,而你似乎是,请阅读汇编程序并查看代码。如果你只有两个小函数只有每种类型的循环,输出不是那么难读,真的,不要害怕。我建议用C来做,但这可能最接近装配,最容易识别零件。

您没有告诉我们您使用的系统/编译器。使用gcc,选项将为-S -O3 -march=native,以使其生成.s文件。