for loop VS while while in programming language,c ++ / java?
哪个性能更好? 这可能与其他编程语言不一致,因此如果它们不同,或者您可以用您对特定语言的知识回答我的问题,请解释。
我将使用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循环更好的选择? 我看到的问题有点类似于此,但我不认为这是重复的,或者其他问题的任何答案都回答了我的问题。
我想要解释这个问题,解释它是否是编译器特定的,它是如何工作的,或者对这个问题的任何好的答案。
我发现很难想象你给出的代码示例会有不同的性能特征。
我对你有一点温和的好奇心。 在类似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()
。
如果发现评估环路限制是昂贵的,那么这种差异可能是相关的。 当然,在循环外部计算List.getCount()
并将结果存储在局部变量中是微不足道的。
比较了Pascal和C / C ++的for
循环,我会说Pascal版本相比之下非常简单。 这不一定是坏事,因为对于更复杂的事情,总是有可用的。
所有敏感的编译器都应该编译等效的循环到相同的汇编/ IL代码,包括分支和跳转。 (至少启用了优化)
在某些CPU架构上,循环的特性可能提供比选择for
和while
更多优化的机会。
特别是, FORTRAN
和Pascal
建议一些CPU可以优化的循环迭代次数的常量(而不是变量)。 例如,在Cyber(20世纪70年代的铁恐龙主机)上,15位寄存器保存了可以轻松比较的for
循环索引。 而是使用一个或两个难以访问的60位寄存器。 此外,Cyber分支指令比循环管理或可能的循环内容昂贵得多。 在这种情况下,高级别的优化可能会展开循环以避免所有开销。
但是,现代代码生成器不像以前那样工作:源代码变成了一个中间解析结构,它抽象出这些选择。 简而言之, for
与while
没有区别。
您发布的示例实际上对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
循环。
int age = 17; // This was made for something else in the code for (; age < 25; age++) { cout << age << endl; }
我认为编译器现在已经足够优化了,所以如果你使用for循环或while循环它真的没有区别。
我建议你写一个小例子和时间差异。 然后选择您发现的最快的解决方案。
你提出的问题是不对的。 循环中的IO占据了循环处理语句可以添加至少一个数量级的所有内容。 我的赌注甚至是你无法测量任何显着差异,因为它与IO产生的噪声(在测量方面)无法区分。
如果循环中的代码真的很快,那么事情才重要。 这里的快速意义甚至没有内存读取指令,从那以后CPU内存带宽将再次占主导地位。
所以如果你真的好奇,而且你似乎是,请阅读汇编程序并查看代码。 如果你只有两个小函数只有每种类型的循环,输出不是那么难读,真的,不要害怕。 我建议用C做,但这可能是最接近assembly的,最容易识别零件。
你没告诉我们你是什么系统/编译器。 使用gcc,选项将是-S -O3 -march=native
以使其生成.s
文件。
它与编译器优化没有任何区别!
我的2,当它涉及循环实现选择时,重要的是使用适合算法逻辑的那个。 阅读代码更容易。