人々は最適化が大好きです。理解しやすく、応用しやすいです…。しかし少し前、Twig のプル リクエストを見ているときに、PHP の三項演算子のパフォーマンスに関する興味深い議論を読みました。
次のスニペットのうちどれが最も速いかわかりますか (もちろん、まったく同じことを行います)。
// snippet 1 $tmp = isset($context['test']) ? $context['test'] : ''; // snippet 2 if (isset($context['test'])) { $tmp = $context['test']; } else { $tmp = ''; }
正解は次のとおりです。
状況によります。ほとんどの場合、速度は同じなので、気にする必要はありません。ただし、$context['test'] に大量のデータが含まれている場合、スニペット 2 はスニペット 1 よりもはるかに高速です。
これは、さまざまなシナリオをテストするために使用したコードです:
$context = array('test' => true); // optionally fill-in the test value with lots of data for ($i = 0; $i < 100000; $i++) { $context['test'][$i] = $i; } // you can also just create a big string // $context = str_repeat(' ', 1000000); // benchmark $time = microtime(true); for ($i = 0; $i < 100; $i++) { // the snippet of code to benchmark $tmp = isset($context['test']) ? $context['test'] : ''; } printf("TIME: %0.2d\n", (microtime(true) - $time) * 1000);
Note、ここでの絶対的なパフォーマンス数値は意味がありません。異なるクリップ間の速度を比較したいだけです。
私のラップトップでは、スニペット 1 の実行には 2 秒以上かかりますが、スニペット 2 の実行には約 0.05 ミリ秒かかります。これは大きな違いです! しかし、テストされる変数が大量のデータを運ばない場合、速度はほぼ同じです。
それでは、なぜ三項演算子は場合によっては遅いのでしょうか?なぜテスト変数に格納されている値に依存するのでしょうか?
答えは非常に簡単です:
##三項演算子は常に値をコピーしますが、if ステートメントは値をコピーしません。その理由は、PHP がコピーオンライトと呼ばれる手法を使用しているためです。つまり、変数に値を代入するとき、PHP は変更されるまで変数の内容のコピーを実際には作成しません。 $tmp = $context['test'] のようなステートメントを作成すると、ほとんど何も起こりません: $tmp 変数は $context['test'] 変数への参照になるだけです。速い。ただし、変数を変更したい場合はすぐに、PHP は元の変数をコピーする必要があります。$tmp = $context['test']; // the copy happens now $tmp[] = true; // copy also happens if the original variable changes // $context['test'][] = true;要約すると、三項演算子の速度は、三項演算子の結果をコピーするのにかかる時間に直接関係します。厳密に必須ではない場合でも、ステートメントを使用します。 100,000 要素の配列をコピーするには時間がかかります。 PHP 5.3 を使用している場合は、新しい ?:construct::
$tmp = $context['test'] ?: '';を使用してステートメントを表現する簡単な方法があります。ただし、パフォーマンスの点では、この新しい Construct にも同じ欠点があります。 PHP は変数が存在する場合を最適化できる場合がありますが、標準構造として使用されます。
以上がPHP 三項演算子: 速いかどうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。