循环更多/更少但具有相同数量的O(1)操作的算法的性能

时间:2018-06-19 17:21:34

标签: loops optimization time-complexity

每当我看到算法优化时,就会看到很多关于减少循环数的讨论。通常,我看到多个操作被合并到一个循环中,这些操作本来是单独完成的。

最终,将执行相同数量的O(1)处理。只是一种算法将它们拆分为多个迭代。从扩展的角度来看,合并操作是否确实对性能有好处?

过于简化的示例。我知道这不是一个很好的例子,因为与偶数i相比,内部时间复杂度运算的效率较低,但是您明白我的意思。

let tally1 = 0
let tally2 = 0

for (let i = 0; i < 10; i++) {
  tally1 += 1
}

for (let i = 0; i < 10; i++) {
  tally2 += 1
}

// vs

for (let i = 0; i < 10; i++) {
  tally1 += 1
  tally2 += 1
}

2 个答案:

答案 0 :(得分:1)

很明显,第二个版本的性能会更好,因为构成循环的所有操作只需执行一次即可。

因此,尽管在循环内执行的操作不会好坏,但总的执行时间会缩短。

是否相关与否很大程度上取决于循环内的操作有多昂贵。如果它们很便宜,则循环的开销将很明显,可能值得优化代码。如果它们很昂贵,那可能不值得付出努力。

除了性能之外,代码的清晰也是一件好事。因此,如果从性能的角度来看没关系,则应选择更易于阅读的代码。

答案 1 :(得分:1)

在非常短的循环中,循环结构本身的开销(增量和终止测试)是“显着的”。编译器可能会执行“循环展开”优化,即复制循环主体以避免执行中间测试(要格外小心以处理终止)。

循环合并可以带来类似的加速效果。

当循环主体变得更加复杂时,循环开销变得可以忽略不计,并且合并循环时性能甚至可能下降,因为您可能会饱和所需的寄存器数量或降低缓存效率。

对于普通程序,这类微优化通常不值得付出努力。它们在开发具有通用性的可重用代码(例如BLAS例程)中更相关。