什么是更好的使用in_array()和||运营商?

时间:2013-01-28 17:57:17

标签: php arrays performance

考虑到脚本的性能,我问这个问题。知道PHP数组的表现不是很好,我在这种情况下徘徊哪种方式是最好的。

假设$x等于a或b或c或d,我们需要执行action_a(),如果不是action_b()则执行..

我们可以使用||运算符实现此操作,如下所示;

if($x == 'a' || $x == 'b' || $x == 'c' || $x == 'd'){
       action_a();
}else{
       action_b();
}

或者我们可以使用in_array()实现此目的,如下所示;

if(in_array($x,array('a','b','c','d'))){
       action_a();
}else{
       action_b();
}

我想知道的是这两个选项中的哪一个会表现良好:

  1. $x的可能值数何时高?

  2. $x的可能值数何时低?

4 个答案:

答案 0 :(得分:6)

Write a benchmark script.

总的来说,选择哪种变体几乎不应该依赖于性能。特别是在输入数据非常小的超级微不足道的情况下(例如< 10)。

这个最重要的标准是始终可读性。

只有在存在无法识别的性能问题时才开始优化代码。

Premature optimization is the root of all evil

答案 1 :(得分:3)

对于大量值,我不会使用任何一种方法。我将创建一个关联数组,其键是可能的值,并使用isset()

$test_array = array_flip(array('a', 'b', 'c', 'd', ...));
if (isset($test_array[$x])) ...

创建$test_array需要一次性O(n)成本,然后检查匹配是否为O(1)。

答案 2 :(得分:3)

这取决于您使用的PHP版本。 PHP 5.3 in_array()上会慢一些。但在 PHP 5.4或更高版本in_array()会更快

只有当您认为情况会随着时间的推移而增长或者这种情况应该是动态的时候,请使用in_array()

我做了一个基准测试。循环你的条件10,000次。

PHP 5.3.10

的结果
+----------------------------+---------------------------+
| Script/Task name           | Execution time in seconds |
+----------------------------+---------------------------+
| best case in_array()       | 1.746                     |
| best case logical or       | 0.004                     |
| worst case in_array()      | 1.749                     |
| worst case logical or      | 0.016                     |
| in_array_vs_logical_or.php | 3.542                     |
+----------------------------+---------------------------+

PHP 5.4

的结果
+----------------------------+---------------------------+
| Script/Task name           | Execution time in seconds |
+----------------------------+---------------------------+
| best case in_array()       | 0.002                     |
| best case logical or       | 0.002                     |
| worst case in_array()      | 0.008                     |
| worst case logical or      | 0.010                     |
| in_array_vs_logical_or.php | 0.024                     |
+----------------------------+---------------------------+

最佳案例:匹配第一个元素 最坏情况匹配最后元素。

这是代码。

$loop=10000;
$cases = array('best case'=> 'a', 'worst case'=> 'z');
foreach($cases as $case => $x){
    $a = utime();
    for($i=0;$i<$loop; $i++){
        $result = ($x == 'a' || $x == 'b' || $x == 'c' || $x == 'd' || $x == 'e' || $x == 'f' || $x == 'g' || $x == 'h' || $x == 'i' || $x == 'j' || $x == 'k' || $x == 'l' || $x == 'm' || $x == 'n' || $x == 'o' || $x == 'p' || $x == 'q' || $x == 'r' || $x == 's' || $x == 't' || $x == 'u' || $x == 'v' || $x == 'w' || $x == 'x' || $x == 'y' || $x == 'z');
    }
    $b = utime();
    $ar = array('a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z');
    for($i=0;$i<$loop; $i++){
        $result = in_array($x, $ar);
    }
    $c = utime();

    $Table->addRow(array("$case in_array()", number_format($c-$b, 3)));
    $Table->addRow(array("$case logical or", number_format($b-$a, 3)));
}

以下utime()microtime()的包装,它在float中提供微秒,$TableConsole_Table实例。

答案 3 :(得分:0)

你的第一个解决方案在性能方面非常有效,当你不需要改变任何东西之后,但是你需要检查的值越多,代码的可读性就越差。

使用数组时,您可以根据需要动态扩展它。 它还可以保持代码清洁。

据我所知,与使用循环的手动搜索相比,in_array函数的性能相当低。

此外,您可以声明所谓的“地图”:

$actions = [
  "a" => function(){ action_a() ; },
  "b" => function(){ action_b() ; }
] ;

之后,你会这样:

if (isset($actions[$x])) 
  $action[$x]() ;
else
  do_smth() ;

小提示: 如果你使用PHP&gt; = 5.4,你可以像这样声明一个新数组:

$array = [1,2,3,4,5] ;
$array[] = "I am a new value to push" ;