什么是更快:很多ifs,否则如果?

时间:2009-11-25 10:45:30

标签: php micro-optimization

我正在迭代一个数组并按值将其分类为一周中的几天。

为了做到这一点,我使用了很多if语句。如果我使用多个if s而不是一组else if语句,它对处理速度有什么影响吗?

11 个答案:

答案 0 :(得分:44)

是的,请使用else if,请考虑以下代码:

if(predicateA){
  //do Stuff
}
if(predicateB){
  // do more stuff
}

if(predicateA){
  //
}
else if(predicateB){
  //
}

在第二种情况下,如果predicateA为true,则不需要评估predicateB(以及任何进一步的谓词)(因此整个代码将执行得更快),而在第一个示例中,如果predicateA为true,则predicateB仍将始终如果谓词A和谓词B不相互排斥,你可能会得到一些意想不到的惊喜。

答案 1 :(得分:17)

我怀疑像这样的微优化会在你的代码中产生可衡量的差异。

您的排序算法更有可能成为性能问题的根源。您选择哪种排序算法至关重要,而不是很多“ifs”与“else if”。

更新:

由于其早期退出和独有的逻辑特征,其他人提出的关于“否则如果”是更好的选择的观点表明,在这种情况下它应优先于“if”。

但关于算法选择的观点仍然存在 - 除非你的数据集非常小。

显然O(log n)优于O(n ^ 2),但数据集的大小也很重要。如果您只有几个元素,您可能不会注意到差异。在这种情况下,编写一个最干净,最易读,最容易理解的低效方法一目了然可能是你最好的选择。

答案 2 :(得分:9)

您可以查看phpbench

但说实话,如果你想在这个级别进行优化,你可能想要学习别的东西而不是php。

alt text

答案 3 :(得分:8)

说实话,我觉得你在性能方面做的不重要,我怀疑你会看到任何不同。我建议使用一个不是性能增强的switch语句,只需语法更好:

switch ($day) 
{
    case "Monday":
        // do something with Monday
        break;
    case "Tuesday":
        // do something with Tuesday
        break;
    case "Wednesday":
        // do something with Wednesday
        break;
}

答案 4 :(得分:3)

else if在您进行比较的意义上会更快,直到您达到解析为true的条件,并且您跳过if的其余部分。

还考虑按频率下降的顺序重新排序比较。

根据您要比较的对象的数据类型使用switch语句。

然而在这一点上,正如duffymo建议的那样,你将进行微观优化。如果您没有首先为作业选择正确的排序算法,性能增益将永远不会那么显着。

答案 5 :(得分:3)

如果连续的if()和if()之间存在真正的差异,那么我做了一个基准测试,然后是一些elseif()

我放了一个大字符串,每次使用两种方法做了大约20次strpos()(x100 000)并显示了这个结果:

Try 1 : 0.5094 (including elseif)
Try 2 : 0.6700 (including only if)

毫无疑问。我已经知道过度的elseif()更快,即使中间有回归;在答案中加入一些统计数据仍然很好。

答案 6 :(得分:2)

如果值是整数,则可以使用表查找来实现优化。例如。假设您有256个值以某种方式映射到7天,您可以设置一个包含256个单元格的数组,每个单元格包含您想要的星期几。然后代替:


if ( value == 0 ) {
  dayofweek = 1;
} else if ( value == 1 ) {
  dayofweek = 2;
} else if ( value == 2 ) {
  dayofweek = 3;
} else if ...

..你可以......


dayofweek = lookuparray[value];

当然,如果你使用这种技术,那么你应该首先检查值的界限。

答案 7 :(得分:1)

我会选择另一个投票来代替选择switch()语句。

答案 8 :(得分:0)

一般来说,“else if”样式可以更快,因为在ifs系列中,每个条件都是一个接一个地检查;在“else if”链中,一旦一个条件匹配,其余条件就被绕过。

最快的是表调度,这是一个switch语句在其中有足够的情况时被优化的内容(如果交换机中的情况很少,它会被转换为一系列if-else检查。结果机器代码)。

答案 9 :(得分:0)

使用许多if语句或if ifs-ifif-elseif的决定不应该依赖于性能,因为这个决定涉及大量的程序流程。

我怀疑你可以在不失去功能的情况下从多个if语句切换到一个大的if-elseif。

这是一个设计问题,而非性能问题。

答案 10 :(得分:0)

if块返回时,这个问题特别有趣,从而完成了方法。它也直接适用于Java中比较器的工作方式。

因此我运行每个方法(下图)250.000.000次,结果如下:

two values   if/else    - 6.43 millis
three values if/else/if - 8.66 millis
three values if/if      - 9.01 millis

虽然最糟糕的情况需要比最好的情况长1.4倍,但会注意到这是累计这些方法中的每一个2.5亿次的总和。假设人类感知延迟需要100ms,而最差/更好的差异是2.58毫秒,这意味着您需要几乎万亿(1000 * 1000百万)次迭代来感知不同方法之间的差异。

总结一下:使用if-else这是其中一种情况,其中最快的选项也是具有更易读性且不易出错的选项。

// methods used to measure difference between if and if/else

/** equality is not important **/
private static int comparatorOfIfElse(int a, int b) {
    if(a < b) return -1;
    else return  1;
}

/** equality is taken into account using if/else **/
private static int comparatorOfIfElseIf(int a, int b) {
    if(a < b) return -1;
    else if(a > b) return  1;
    return 0;
}

/** equality is taken into account using only if **/
private static int comparatorOfIf(int a, int b) {
    if(a < b) return -1;
    if(a > b) return  1;
    return 0;
}