【问题标题】:When looping through an array, is there a way to avoid doing a comparison upon each loop?遍历数组时,有没有办法避免对每个循环进行比较?
【发布时间】:2015-01-16 06:55:36
【问题描述】:

假设一个循环总是在某个序列中一次迭代一个循环,我想知道是否有一些巧妙的循环结构或技巧可以避免在每次迭代时检查数组的末尾 >。

for (int i=0; i<length; i++) { 
    //something 
}

int i=0;
while (i<length) { 
    //something 
    i++;
}

为澄清起见,我指的是上面示例中的比较(i&lt;length)

如果相关,我通常使用 C++ 编写代码,但愿意听取其他提供解决此问题的方法的语言。

【问题讨论】:

  • 当然,它被称为loop unrolling,许多编译器会自动完成
  • for(;;){/* something */},当然=D

标签: c++ loops for-loop while-loop iteration


【解决方案1】:

我想知道是否有一些巧妙的循环结构或技巧可以避免在每次迭代时检查数组的末尾。

将 i 设置为长度,然后在循环的每次迭代中递减 i。

int i = length;
while ( i-- >= 0) {
  // do something
}

【讨论】:

  • 您在问题的措辞中发现了漏洞,但不符合其精神
  • 你是说对 0 的检查在某种程度上比对非零整数的检查在内部更快?
  • 它这样做“避免在每次迭代时检查数组末尾。”
【解决方案2】:

是的,您可以像这样展开循环:

int i;
for (i = 0; i < length - 3; i += 4) { // 4x unrolled loop
    //something(i)
    //something(i+1)
    //something(i+2)
    //something(i+3)
}
for ( ; i < length; i++) {           // clean up loop for residual 0..3 iterations
    //something(i)
}

【讨论】:

  • 手动展开循环会使编译器更难自己(可能更优化)展开,对吗?
  • @sgarza62: 如果你知道自己在做什么,那么手动展开有时比让编译器来做更有效率,但这种事情通常是不得已而为之,通常不应该这样做手动,除非您确定循环是瓶颈。您还需要进行基准测试并确保您的展开版本优于编译器的版本。
【解决方案3】:

你可以展开循环:

int length = 20 ;
int i=0;
while (i+3<length) { 
    //something 
    i++;
    //something 
    i++;
    //something 
    i++;
    //something 
    i++;
}

//handle any remaining cases
while (i<length) { 
    //something 
    i++ ;
}

【讨论】:

    猜你喜欢
    • 2022-11-22
    • 2021-11-10
    • 1970-01-01
    • 2019-04-14
    • 2021-03-15
    • 1970-01-01
    • 2015-05-23
    • 2018-08-02
    • 2018-08-10
    相关资源
    最近更新 更多