2

スクリプトのパフォーマンスを考慮して、この質問をしています。PHP配列のパフォーマンスがあまり良くないことを知っているので、このような状況でダウンするのに最適な方法を迷っています。

$xaまたは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();
}

私が知りたいのは、これら2つのオプションのどちらがうまく機能するかということです。

  1. の可能な値の数が多い場合は$x

  2. の可能な値の数$xが少ない場合は?

4

4 に答える 4

6

ベンチマークスクリプトを作成します。

ただし、一般的に、どのバリアントを選択するかは、パフォーマンスにほとんど依存しないはずです。特に、入力データが非常に小さい(たとえば<10)非常に些細な場合。

この最も重要な基準は、常に読みやすさです。

否定できないパフォーマンスの問題がある場合にのみ、コードの最適化を開始してください。

時期尚早の最適化はすべての悪の根源です

于 2013-01-28T18:00:16.383 に答える
3

値の数が多い場合は、どちらの方法も使用しません。キーが可能な値である連想配列を作成し、以下を使用しますisset()

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

これには、作成に1回限りのO(n)コストがかかり$test_array、一致するかどうかのチェックはO(1)です。

于 2013-01-28T18:05:23.127 に答える
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)));
}

これはfloat でマイクロ秒を提供utime()する のラッパーであり、インスタンスです。microtime()$TableConsole_Table

于 2013-01-28T18:15:11.373 に答える
0

最初のソリューションは、パフォーマンスの場合、後で何も変更する必要がない場合に非常にうまく機能しますが、チェックする必要のある値が増えるほど、コードの可読性が低下します。

アレイを使用している間、必要に応じて動的に拡張できます。また、コードをクリーンに保ちます。

私の知る限り、in_array関数は、ループを使用した手動検索に比べてパフォーマンスがかなり低くなっています。

また、いわゆる「マップ」を宣言することもできます。

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

そしてその後、あなたはこれが好きです:

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

ちょっとしたヒント:PHP> = 5.4を使用している場合は、次のように新しい配列を宣言できます。

$array = [1,2,3,4,5] ;
$array[] = "I am a new value to push" ;
于 2013-01-28T18:12:15.187 に答える