哪个循环有更好的性能? 增加还是减少?

可能重复:
倒计时比倒数更快吗?

哪个循环有更好的性能? 我从一些地方学到了第二个更好的地方。 但想知道原因。

for(int i=0;i=0;i--) { /*This is better ?*/ } 

第二个“可能”会更好,因为将i与0进行比较比将i与10进行比较更容易,但我认为你可以使用其中任何一个,因为编译器会优化它们。

认为两个循环的性能有很大差异。

我想,当循环看起来像这样时,它会变成另一种情况。

 for(int i = 0; i < getMaximum(); i++) { } for(int i = getMaximum() - 1; i >= 0; i--) { } 

因为getMaximum()函数被调用一次或多次(假设它不是内联函数)

如果在硬件中优化针对零的测试,则减少循环降至零有时会更快。 但这是一个微观优化,你应该分析一下它是否真的值得做。 编译器通常会为您进行优化,并且假设减量循环可以说是更糟糕的意图表达,那么通常只需坚持使用“正常”方法就可以了。

递增和递减(INC和DEC,当转换为汇编程序命令时)具有相同的1 CPU周期速度。

然而,在某些(例如SPARC)架构上,第二个理论上可以更快 ,因为不必从内存(或缓存)中获取10 :大多数架构都有指令,当与特殊值0 (通常具有特殊的硬连线0寄存器用作操作数,因此每次迭代的比较都不需要“浪费”寄存器来存储10

智能编译器(特别是如果目标指令集是RISC)本身将检测到这一点并且(如果您的计数器变量未在循环中使用)应用第二个“递减downto 0”表单。

有关更多详细信息,请参阅答案https://stackoverflow.com/a/2823164/1018783和https://stackoverflow.com/a/2823095/1018783 。

编译器应该将两个代码优化到同一个程序集,因此它没有什么区别。 两者都需要同一时间。

更有效的讨论是否是

  for(int i=0;i<10;++i) //preincrement { } 

会更快

  for(int i=0;i<10;i++) //postincrement { } 

因为理论上,后增量会执行额外的操作(返回对旧值的引用)。 但是,即使这应该优化到相同的组件。

如果没有优化,代码将如下所示:

  for ( int i = 0; i < 10 ; i++ ) 0041165E mov dword ptr [i],0 00411665 jmp wmain+30h (411670h) 00411667 mov eax,dword ptr [i] 0041166A add eax,1 0041166D mov dword ptr [i],eax 00411670 cmp dword ptr [i],0Ah 00411674 jge wmain+68h (4116A8h) for ( int i = 0; i < 10 ; ++i ) 004116A8 mov dword ptr [i],0 004116AF jmp wmain+7Ah (4116BAh) 004116B1 mov eax,dword ptr [i] 004116B4 add eax,1 004116B7 mov dword ptr [i],eax 004116BA cmp dword ptr [i],0Ah 004116BE jge wmain+0B2h (4116F2h) for ( int i = 9; i >= 0 ; i-- ) 004116F2 mov dword ptr [i],9 004116F9 jmp wmain+0C4h (411704h) 004116FB mov eax,dword ptr [i] 004116FE sub eax,1 00411701 mov dword ptr [i],eax 00411704 cmp dword ptr [i],0 00411708 jl wmain+0FCh (41173Ch) 

所以即使在这种情况下,速度也是一样的。

同样,所有微观绩效问题的答案都是衡量 ,衡量使用的背景,而不是推断到其他情境。

在很长一段时间内没有非常复杂的情况下,计数指令执行时间是不可能的。

处理器和内存速度之间的不匹配以及引入缓存以隐藏部分延迟(但不是带宽)使得一组指令的执行对内存访问模式非常敏感。 这是你仍然可以通过相当高水平的思考来优化的东西。 但是,这也意味着,如果不考虑内存访问模式,那么一旦完成就会更好。

然后超标量(处理器可以同时执行多项操作)和乱序执行(处理器可以在流中的前一个之前执行指令的事实)使得即使您忽略内存访问,基本计数也毫无意义。 您必须知道需要执行哪些指令(因此忽略部分结构并不明智)以及如果您希望获得良好的先验估计,处理器可以如何对指令进行分组。