哪种性能更好?这可能与其他编程语言不一致,因此如果它们不同,或者您可以用您对特定语言的知识回答我的问题,请解释。
我将使用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循环更好的选择?我看到的问题有点类似于此,但我不认为这是重复的,或者其他问题的任何答案都回答了我的问题。
我希望对这个问题有一个解释,解释它是否是编译器特定的,它是如何工作的,或者对这个问题有什么好的答案。
答案 0 :(得分:4)
所有合理的编译器都应该编译等效的循环到相同的汇编/ IL代码,包括分支和跳转。 (至少启用了优化)
答案 1 :(得分:3)
在某些CPU架构上,循环的特征可能提供比for
与while
的选择更多优化的机会。
特别是,FORTRAN
和Pascal
建议一些CPU可以优化的循环迭代次数的常量(而不是变量)。例如,在Cyber(20世纪70年代的铁恐龙主机)上,15位寄存器保存for
循环索引,可以轻松进行比较。而while
使用一个或两个难以访问的60位寄存器。此外,Cyber分支指令比循环管理或可能的循环内容昂贵得多。在这种情况下,高级别的优化可能会展开循环以避免所有开销。
然而,现代代码生成器不像以前那样工作:源代码变成了一个中间解析结构,它抽象出这些选择。简而言之,for
与while
没有任何区别。
答案 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)
您发布的示例实际上对while
和for
有不同的行为。
此:
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
文件。