26

我正在遍历一个数组并按值将其排序为一周中的几天。

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

4

11 回答 11

51

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

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

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

在第二种情况下,如果 predicateA 为真,则不需要计算 predicateB(和任何其他谓词)(因此整个代码将执行得更快),而在第一个示例中,如果 predicateA 为真,则仍将始终计算 predicateB,如果 predicateA 和 predicateB 不是互斥的,你也可能会得到一些意想不到的惊喜。

于 2009-11-25T10:54:50.700 回答
21

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

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

更新:

其他人关于“else if”是一个更好的选择的观点,由于它的早期退出和排他的逻辑特性,表明在这种情况下它应该优先于“if”。

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

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

于 2009-11-25T10:52:10.970 回答
12

你可以看看phpbench

但老实说,如果你想在这个级别进行优化,你可能想学习 php 以外的其他东西。

替代文字

于 2009-11-25T11:09:41.247 回答
9

老实说,我认为您在性能方面采用哪种方式并不重要,我怀疑您会看到任何差异。我建议使用不是性能增强的 switch 语句,只是在语法上更好:

switch ($day) 
{
    case "Monday":
        // do something with Monday
        break;
    case "Tuesday":
        // do something with Tuesday
        break;
    case "Wednesday":
        // do something with Wednesday
        break;
}
于 2009-11-25T10:53:46.337 回答
5

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

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

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

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

于 2013-08-26T20:51:17.317 回答
4

else if从比较的意义上讲会更快,直到您遇到一个解析为真的条件,并且您跳过其余的ifs.

还可以考虑按频率降序对比较进行重新排序。

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

但是,正如 duffymo 所建议的那样,此时您将进行微优化。如果您没有首先为工作选择正确的排序算法,那么性能提升将永远不会那么显着。

于 2009-11-25T10:52:30.173 回答
3

如果值是整数,您可以通过使用表查找来实现优化。例如,假设您有 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];

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

于 2009-11-25T10:56:10.653 回答
1

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 亿次的总和。假设人类感知延迟需要 100 毫秒,并且最差/更好的差异是 2.58 毫秒,这意味着您需要近一万亿次(1000 * 10 亿)次迭代才能感知不同方法之间的差异。

总结一下:使用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;
}
于 2014-01-28T20:10:16.533 回答
1

我会再次投票选择 switch() 语句。

于 2009-11-25T13:05:00.697 回答
0

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

我怀疑您是否可以在不丢失功能的情况下从许多 if 语句切换到大型 if-elseif。

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

于 2009-11-25T11:09:09.487 回答
0

一般来说,“else if”风格会更快,因为在一系列 if 中,每个条件都被一个接一个地检查;在“else if”链中,一旦匹配了一个条件,其余的就会被绕过。

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

于 2009-11-25T11:01:58.727 回答