16

次のことを行う方が速いですか?

 if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') { ... }

または:

 if (!in_array($var, array('test1', 'test2', 'test3', 'test4') { ... }

どちらか一方を実行する方が速い時点で、いくつかの値がありますか?

(この場合、2 番目のオプションで使用される配列はまだ存在しません。)

4

10 に答える 10

18

を使用することを強くお勧めしin_array()ます。速度の違いは無視できますが、各変数を個別にテストすることの可読性は恐ろしいものです。

楽しみのために、私が実行したテストを次に示します。

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
$end = microtime(true);

print "Time1: ". ($end - $start)."<br />";

$start2 = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array) ) {}
}
$end2 = microtime(true);

print "Time2: ".($end2 - $start2)."<br />";

// Time1: 1.12536692619
// Time2: 1.57462596893

が設定されていない場合$var、メソッド 1 ははるかに時間がかかります (テストする条件の数によって異なります)。

新しい PHP バージョンの更新:

Martijn:平均的なケースとして、配列を5 つの要素に拡張し、 を探しました。test3

PHP5.6

Time1: 0.20484399795532
Time2: 0.29854393005371

PHP7.1

Time1: 0.064045906066895
Time2: 0.056781053543091

PHP7.4

Time1: 0.048759937286377
Time2: 0.049691915512085

PHP8.0

Time1: 0.045055150985718
Time2: 0.049431085586548

結論: 元のテストは最適なテストではありませんでした。さらに: php7+ では好みの問題になっています。

于 2008-11-27T21:21:51.790 に答える
9

!==一連のステートメントを置き換える場合は、3 番目のパラメーターをin_arrayastrueに渡す必要があることに注意してください。これにより、配列内の項目の型チェックが強制されます。

明らかに、通常!=はこれを必要としません。

于 2008-11-28T01:43:02.167 に答える
6

前者の方が高速です。後者の方がオーバーヘッドが大きくなります。配列の作成、関数の呼び出し、配列の検索などです。

ただし、質問でいくつかの回答を下に述べたように、時期尚早の最適化はすべての悪の根源です。コードは読みやすいように記述し、最適化する必要がある場合はプロファイルして最適化します。

編集:

@Owen のコード (PHP 5.2.6/windows) での私のタイミング:

Time1: 1.33601498604
Time2: 4.9349629879

質問のように、ループ内で array(...) を移動します。

Time1: 1.34736609459
Time2: 6.29464697838
于 2008-11-27T21:22:13.070 に答える
3

こんにちは、私はこのケースを極端に取り上げて、値の数が増えるにつれて単純な比較が最もパフォーマンスの高い方法ではないことを指摘しました。

これが私のコードです:

$var = 'test';
$num_values = 1000;
$iterations = 1000000;
print "\nComparison performance test with ".$num_values." values and ".$iterations." loop iterations";
print "\n";

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test0' &&
        $var != 'test1' &&
        // ...
        // yes I really have 1000 lines in my file
        // ...
        $var != 'test999') {}
}
print "\nCase 1: plain comparison";
print "\nTime 1: ". (microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array1[] = 'test'.$i;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array1) ) {}
}
print "\nCase 2: in_array comparison";
print "\nTime 2: ".(microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array2['test'.$i] = 1;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array2[$var])) {}
}
print "\nCase 3: values as keys, isset comparison";
print "\nTime 3: ".(microtime(true) - $start);
print "\n";

$start = microtime(true);
$array = array();
for($i=0; $i<$num_values; $i++) {
    $array3['test'.$i] = 1;
}
for($i = 0; $i < $iterations; ++$i) {
    if (!array_key_exists($var, $array3)) {}
}
print "\nCase 4: values as keys, array_key_exists comparison";
print "\nTime 4: ".(microtime(true) - $start);
print "\n";

私の結果(PHP 5.5.9):

Case 1: plain comparison
Time 1: 31.616894006729

Case 2: in_array comparison
Time 2: 23.226133823395

Case 3: values as keys, isset comparison
Time 3: 0.050863981246948

Case 4: values as keys, array_key_exists comparison
Time 4: 0.13700890541077

私は同意します、それは少し極端ですが、PHP のハッシュ テーブルのような連想配列の全体像と大きな可能性を示しています。

于 2014-12-11T08:52:40.823 に答える
2

in_array は、アイテム数が多い場合に高速になります。「大」は、データとコンピューターに関連する多くの要因に基づいて、非常に主観的なものです。あなたが尋ねているので、些細な数のアイテムを扱っていないと思います。より長いリストについては、この情報に注意し、フリップ配列でパフォーマンスを測定して、PHP が線形検索の代わりにハッシュ ルックアップを利用できるようにします。「静的」配列の場合、微調整してもパフォーマンスは向上しない可能性がありますが、向上する可能性もあります。

Owen のテスト コードを使用して、反転した配列とより多くの反復を使用して、より一貫した結果を得ます。

$array2 = array_flip($array);
$iterations = 10000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array2[$var])) {}
}
$end = microtime(true);
print "Time3: ".($end - $start)."<br />";

Time1: 12.875
Time2: 13.7037701607
Time3: 3.70514011383
于 2008-11-27T21:26:04.230 に答える
1

RoBorg が指摘したように、配列の作成にはオーバーヘッドがあるため、反復ループ内に移動する必要があることに注意してください。このため、array_flip 関数のオーバーヘッドがあるため、Sparr の投稿も少し誤解を招きます。

5 つのバリエーションすべてを含む別の例を次に示します。

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
print "Time1: ". (microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if (!in_array($var, $array) ) {}
}
print "Time2: ".(microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
   if (!in_array($var, array('test1', 'test2', 'test3', 'test4')) ) {}
}
print "Time2a: ".(microtime(true) - $start);

$array2 = array_flip($array);
$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
  if (!isset($array2[$var])) {}
}
print "Time3: ".(microtime(true) - $start);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    $array2 = array_flip($array);
  if (!isset($array2[$var])) {}
}
print "Time3a: ".(microtime(true) - $start);

私の結果:

Time1 : 0.59490108493 // straight comparison
Time2 : 0.83790588378 // array() outside loop - not accurate
Time2a: 2.16737604141 // array() inside loop
Time3 : 0.16908097267 // array_flip outside loop - not accurate
Time3a: 1.57209014893 // array_flip inside loop

要約すると、array_flip(isset を使用して) を使用すると inarray よりも高速ですが、単純な比較ほど高速ではありません。

于 2009-02-16T04:04:50.407 に答える
0

私のテスト

$array = array('test1', 'test2', 'test3', 'test4');
$var = 'test';
$iterations = 1000000;

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if ($var != 'test1' && $var != 'test2' && $var != 'test3' && $var != 'test4') {}
}
$end = microtime(true);

print "Time1: ". ($end - $start)."<br />";

$start2 = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!in_array($var, $array) ) {}
}
$end2 = microtime(true);

print "Time2: ".($end2 - $start2)."<br />";

$array_flip = array_flip($array);

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array_flip[$var])) {}
}
$end = microtime(true);
print "Time3: ".($end - $start)."<br />";

$start = microtime(true);
for($i = 0; $i < $iterations; ++$i) {
    if (!isset($array[$var])) {}
}
$end = microtime(true);

print "Time4: ". ($end - $start)."<br />";

時間 1: 0.20001101493835

時間 2: 0.32601881027222

時間 3: 0.072004079818726

時間 4: 0.070003986358643

于 2019-02-08T23:31:23.740 に答える