循环vs双IF语句

时间:2013-11-23 17:50:41

标签: performance

什么会更有效:

For i = 0 to 2
if x[i] == y[i] then do something
//or
if x[0] == y[0] do something
if x[1] == y[1] do something

如果我只做两次。另外,忽略可读性。

3 个答案:

答案 0 :(得分:0)

  

什么会更有效:

我认为两者之间存在绝对没有区别,因为你的for循环只是从0到2,所以你可能更喜欢哪种更具可读性。但是如果for循环很大(即索引非常大),那么我建议使用for循环,因为它更易读。

  

另外,忽略可读性。

我不建议这样做,因为所有程序员总是建议编写对自己和其他人更具可读性的代码。

答案 1 :(得分:0)

这取决于。这几乎总是这些事情的答案。

这里会有几种效果。

首先,有一个循环(即实际上是机器代码中的循环,高级源实际上是无关紧要的,除了它可能影响机器代码,循环2具有极高的机会被编译器展开)清楚地执行更多分支,虽然正确预测的分支通常没有延迟,但它们通常具有有限的吞吐量。

其次,具有两个不同的分支意味着可以将不同的分支预测历史附加到它们。这可以提高它们的可预测性,特别是如果单独采用的模式都适合分支历史缓冲区,但是聚合模式太长而不适合。这是非常依赖于机器的,不会发生在所有微体系结构上,并且在任何情况下都非常罕见,因为它需要可预测的行为模式,这种行为具有精确平衡的“足够长但不太长”的长度。

第三,展开该循环可能会导致更多代码(除非循环开销超过循环体)。这给代码缓存和解码器带来了更大的压力。与前两个不同,这种效果有利于循环。

最后,所有这些影响都很小。在存在任何其他事物(例如缓存未命中)的情况下,它们可能会在噪声中完全消失。

答案 2 :(得分:0)

这不是完全相同的问题,但我一直想知道在同一个循环中做更多工作和迭代两次集之间的性能优势是什么。我认为循环一次会更快,但我不确定多少或者优化是否完全等于它们。

我终于做了一个简单的测试,正如你所料,在同一个循环中做更多的工作要快一点。

测试非常简单,在Swift 3.1中完成并运行优化ON:

let itr = 10000000
let passes = 10
print("Running \(itr) iterations through \(passes) passes")
for run in 0..<passes {
    print("---------")
    var time = CFAbsoluteTimeGetCurrent()
    var val1 = 0
    for i in 0..<itr {
        val1 += i
    }
    for i in 0..<itr {
        val1 += i
    }
    let t1 = CFAbsoluteTimeGetCurrent() - time
    print("\(run).1 - \(val1) -- \(t1)")

    time = CFAbsoluteTimeGetCurrent()
    var val2 = 0
    for i in 0..<itr {
        val2 += i
        val2 += i
    }
    let t2 = CFAbsoluteTimeGetCurrent() - time
    print("\(run).2 - \(val2) -- \(t2)")
}

结果:

Running 10000000 iterations through 10 passes
---------
0.1 - 99999990000000 -- 0.127476990222931
0.2 - 99999990000000 -- 0.0763950347900391
---------
1.1 - 99999990000000 -- 0.121748030185699
1.2 - 99999990000000 -- 0.0743749737739563
---------
2.1 - 99999990000000 -- 0.123345971107483
2.2 - 99999990000000 -- 0.0756909847259521
---------
3.1 - 99999990000000 -- 0.11965000629425
3.2 - 99999990000000 -- 0.0711749792098999
---------
4.1 - 99999990000000 -- 0.117263972759247
4.2 - 99999990000000 -- 0.0712859630584717
---------
5.1 - 99999990000000 -- 0.116972029209137
5.2 - 99999990000000 -- 0.0708900094032288
---------
6.1 - 99999990000000 -- 0.121819019317627
6.2 - 99999990000000 -- 0.0748890042304993
---------
7.1 - 99999990000000 -- 0.124098002910614
7.2 - 99999990000000 -- 0.0734890103340149
---------
8.1 - 99999990000000 -- 0.122666001319885
8.2 - 99999990000000 -- 0.07710200548172
---------
9.1 - 99999990000000 -- 0.121197044849396
9.2 - 99999990000000 -- 0.0715969800949097