我正在遍历一个数组并按值将其排序为一周中的几天。
为了做到这一点,我使用了许多if
语句。if
如果我使用许多s,而不是一组else if
语句,它对处理速度有什么影响吗?
我正在遍历一个数组并按值将其排序为一周中的几天。
为了做到这一点,我使用了许多if
语句。if
如果我使用许多s,而不是一组else if
语句,它对处理速度有什么影响吗?
是的,使用 else if,考虑以下代码:
if(predicateA){
//do Stuff
}
if(predicateB){
// do more stuff
}
的
if(predicateA){
//
}
else if(predicateB){
//
}
在第二种情况下,如果 predicateA 为真,则不需要计算 predicateB(和任何其他谓词)(因此整个代码将执行得更快),而在第一个示例中,如果 predicateA 为真,则仍将始终计算 predicateB,如果 predicateA 和 predicateB 不是互斥的,你也可能会得到一些意想不到的惊喜。
我怀疑像这样的微优化会在您的代码中产生可衡量的差异。
您的排序算法更有可能是性能问题的根源。您选择哪种排序算法将是至关重要的,而不是“ifs”与“else if”。
更新:
其他人关于“else if”是一个更好的选择的观点,由于它的早期退出和排他的逻辑特性,表明在这种情况下它应该优先于“if”。
但是关于算法选择的观点仍然存在——除非你的数据集非常小。
很明显 O(log n) 会比 O(n^2) 好,但数据集的大小也很重要。如果您只有几个元素,您可能不会注意到差异。在这种情况下,以最简洁、最易读、最容易理解的方式编写一个低效的方法可能是你最好的选择。
老实说,我认为您在性能方面采用哪种方式并不重要,我怀疑您会看到任何差异。我建议使用不是性能增强的 switch 语句,只是在语法上更好:
switch ($day)
{
case "Monday":
// do something with Monday
break;
case "Tuesday":
// do something with Tuesday
break;
case "Wednesday":
// do something with Wednesday
break;
}
如果连续的 if() 和 if() 之间存在真正的区别,那么我做了一个基准测试,然后是一些 elseif()
我放了一个大字符串,每次使用这两种方法(x100 000)做了大约 20 个 strpos(),它显示了这个结果:
Try 1 : 0.5094 (including elseif)
Try 2 : 0.6700 (including only if)
毫无疑问。我已经知道连续 elseif() 更快,即使中间有 return ;在答案中加入一些统计数据仍然很好。
else if
从比较的意义上讲会更快,直到您遇到一个解析为真的条件,并且您跳过其余的if
s.
还可以考虑按频率降序对比较进行重新排序。
switch
并根据您要比较的对象的数据类型使用该语句。
但是,正如 duffymo 所建议的那样,此时您将进行微优化。如果您没有首先为工作选择正确的排序算法,那么性能提升将永远不会那么显着。
如果值是整数,您可以通过使用表查找来实现优化。例如,假设您有 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];
当然,如果您使用这种技术,那么您应该首先检查值的界限。
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;
}
我会再次投票选择 switch() 语句。
使用多个 if 语句或一个 if-elseif-elseif... 的决定不应依赖于性能,因为该决定涉及大量的程序流程。
我怀疑您是否可以在不丢失功能的情况下从许多 if 语句切换到大型 if-elseif。
这是一个设计问题,而不是性能问题。
一般来说,“else if”风格会更快,因为在一系列 if 中,每个条件都被一个接一个地检查;在“else if”链中,一旦匹配了一个条件,其余的就会被绕过。
最快的将是一个表调度,这是一个 switch 语句在有足够的 case 时被优化的内容(如果 switch 中的 case 很少,它会被转换为结果机器代码中的一系列 if-else 检查)。