在for循环中倒计时

ohi*_*hit 9 c++ for-loop

我相信(从一些研究阅读中),在for循环中倒计时实际上在运行时更有效,更快.我的完整软件代码是C++

我目前有这个:

for (i=0; i<domain; ++i) {
Run Code Online (Sandbox Code Playgroud)

我的'i'是unsigned resgister int,'domain'也是unsigned int

在for-loop中,i用于遍历数组,例如

array[i] = do stuff
Run Code Online (Sandbox Code Playgroud)

把它转换成倒计时会弄乱我的例行程序的预期/正确输出.

我可以想象答案是微不足道的,但我无法理解它.

更新:'do stuff'不依赖于之前或之后的迭代.for循环中的计算与i的迭代无关.(我希望这是有道理的).

更新:要使用我的for循环实现运行时加速,我是否倒计时,如果是这样,在删除我的int时删除未签名的部分,或者其他什么方法?

请帮忙.

Don*_*eld 31

使用无符号计数器只有一种正向循环方法:

for( i = n; i-- > 0; )
{
    // Use i as normal here
}
Run Code Online (Sandbox Code Playgroud)

这里有一个技巧,对于最后一个循环迭代,你将在循环的顶部有i = 1,i--> 0遍,因为1> 0,然后在循环体中i = 0.在下一次迭代中,i--> 0失败,因为i == 0,所以后缀减量在计数器上滚动并不重要.

我知道非常不明显.

  • 但是小心:那么i--所需的临时拷贝使得从循环中获得的任何性能都相形见绌.即不要将其用作性能优化,在实际需要将无符号计数降为0时使用它. (3认同)
  • Don的循环产生尽可能短的代码:mov esi,n; L1:dec esi; "循环体"; 测试esi,esi; jne L1; (3认同)
  • 请注意,第一个“i”是“n-1”。 (3认同)
  • 不知道这一个.太好了! (2认同)
  • 其实我不同意MadKeithV的评论.实际情况是,对于标准算术类型,所有递减(和递增)都是很好的优化.Don给出的代码将是有效的.我认为现代程序员不太了解编译器/汇编程序的问题,并且认为所有的后递减都是低效的. (2认同)

Jer*_*ten 29

我猜你的后向循环看起来像这样:

for (i = domain - 1; i >= 0; --i) {
Run Code Online (Sandbox Code Playgroud)

在这种情况下,因为i无符号的,所以它总是大于或等于零.当您递减一个等于零的无符号变量时,它将回绕到一个非常大的数字.解决方案要么是i签名,要么改变for循环中的条件,如下所示:

for (i = domain - 1; i >= 0 && i < domain; --i) {
Run Code Online (Sandbox Code Playgroud)

或数domain1而不是domain - 10:

for (i = domain; i >= 1; --i) {
    array[i - 1] = ...; // notice you have to subtract 1 from i inside the loop now
}
Run Code Online (Sandbox Code Playgroud)

  • +1用于捕获溢出.明智的做法是补充说,这种(过早的)微观优化是"万恶之源" - 唐纳德克努特 (6认同)

Hej*_*man 12

这不是您问题的答案,因为您似乎没有问题.

这种优化完全不相关,应留给编译器(如果完成的话).

您是否已分析过您的程序以检查您的for循环是否是瓶颈?如果没有,那么你不需要花时间担心这一点.更重要的是,在你写作时,将"i"作为"寄存器"int,从性能的角度来看并没有真正的意义.

即使不知道你的问题域,我也可以向你保证,反向循环技术和"寄存器"int计数器对你的程序性能的影响可以忽略不计.请记住,"过早优化是所有邪恶的根源".

也就是说,更好地利用优化时间将考虑整体程序结构,使用的数据结构和算法,资源利用率等.


Mic*_*ael 10

检查数字是否为零可以比比较更快或更有效.但这是你真正不应该担心的那种微优化 - 几个时钟周期将与任何其他性能问题相比相形见绌.

在x86上:

dec eax
jnz Foo
Run Code Online (Sandbox Code Playgroud)

代替:

inc eax
cmp eax, 15
jl Foo
Run Code Online (Sandbox Code Playgroud)