0

どちらの構築が速いですか:

$a = $b * $c ? $b * $c : 0;  

また

$i = $b * $c;  
$a = $i ? $i : 0;  

すべての変数はローカル変数です。

掛け算、足し算、引き算、割り算で速度は違う?

アップデート:

ここにいくつかの説明があります:

  1. これは、速度が最適化されたコードをゼロから作成することに関する理論的な質問です。「ボトルネックを探す」ことではありません。
  2. 自分でコード速度を測定できます。しかし、それは microtime() を使用する宿題についての質問ではありませんでした。それは、PHP インタープリターがどのように機能するかについての質問でした (Google を自分で掘り下げて理解しようとしましたが、問題はありませんでした)。
  3. さらに、私は自分で測定しましたが、少し混乱しました. $a、$b、および $c (ゼロ、負、正、整数、および浮動小数点の組み合わせ) の異なる開始値は、構造間で異なる結果を生成します。だから私は混乱しました。

BoltClock は有益な情報を提供してくれましたが、user576875 はオペコード デコーダーへのリンクを投稿することで 1 日を終えました。彼の答えには、私の質問に対する直接の答えも含まれています。ありがとう!

4

3 に答える 3

10

PHP 5.3 を使用している場合は、こちらの方が高速です。

$a = $b * $c ?: 0; 

これは と同じです$a = $b * $c ? $b * $c : 0;が、$a*$b計算は 1 回だけ行われます。また、2 番目のソリューションのように追加の割り当ては行いません。

Martin v. Löwis のベンチマーク スクリプトを使用すると、次のような結果が得られます。

$a = $b * $c ?: 0;               1.07s
$a = $b * $c ? $b * $c : 0;      1.16s
$i = $b * $c; $a = $i ? $i : 0;  1.39s

現在、これらはマイクロ最適化であるため、これを行う前にコードを最適化する方法はおそらくたくさんあります:)

そうでない場合は、生成された PHP OP コードを比較することもできます。

1 $a = $b * $c ? $b * $c : 0;:

number of ops:  8
compiled vars:  !0 = $a, !1 = $b, !2 = $c
line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
   1     0  MUL                                              ~0      !1($b), !2($c)
         1  JMPZ                                                     ~0, ->5
         2  MUL                                              ~1      !1($b), !2($c)
         3  QM_ASSIGN                                        ~2      ~1
         4  JMP                                                      ->6
         5  QM_ASSIGN                                        ~2      0
         6  ASSIGN                                                   !0($a), ~2
         7  RETURN                                                   null

2$i = $b * $c; $a = $i ? $i : 0;

number of ops:  8
compiled vars:  !0 = $i, !1 = $b, !2 = $c, !3 = $a
line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
   1     0  MUL                                              ~0      !1($b), !2($c)
         1  ASSIGN                                                   !0($i), ~0
         2  JMPZ                                                     !0($i), ->5
         3  QM_ASSIGN                                        ~2      !0($i)
         4  JMP                                                      ->6
         5  QM_ASSIGN                                        ~2      0
         6  ASSIGN                                                   !3($a), ~2
         7  RETURN                                                   null

3 $a = $b * $c ?: 0;:

number of ops:  5
compiled vars:  !0 = $a, !1 = $b, !2 = $c
line     #  op                           fetch          ext  return  operands
-------------------------------------------------------------------------------
   1     0  MUL                                              ~0      !1($b), !2($c)
         1  ZEND_JMP_SET                                     ~1      ~0
         2  QM_ASSIGN                                        ~1      0
         3  ASSIGN                                                   !0($a), ~1
         4  RETURN                                                   null

これらの OP コード リストは、VLD拡張機能によって生成されました。

于 2011-01-22T10:50:39.627 に答える
1
<?php
function run(){
$b=10;
$c=10;
$start=gettimeofday(TRUE);
for($k=0;$k<10000000;$k++){
  $a = $b * $c ? $b * $c : 0;  
}
printf("%f\n", gettimeofday(TRUE)-$start);
$start=gettimeofday(TRUE);
for($k=0;$k<10000000;$k++){
  $i = $b * $c;  
  $a = $i ? $i : 0;  
}
printf("%f\n", gettimeofday(TRUE)-$start);
}
run();
?>

私のシステム (PHP 5.3.3、Linux、Core i7 2.8GHz) では、

1.593521
1.512892

したがって、個別の割り当てはわずかに高速です。加算 (* ではなく +) の場合、逆の結果が得られます。

1.386522
1.450358

したがって、実際には自分のシステムでこれらを測定する必要があります。PHP のバージョンが異なると、結果が再び変わる可能性があります。

于 2011-01-22T10:14:04.763 に答える
0

あなたの 2 つのコードにはそれぞれ欠点があります。追加の割り当てを行います。もう 1 つは追加の数学演算を行います。PHP 5.3 の三項演算子を使用すると、次のことが可能になります。

$a = $b * $c ?: 0;

三項の 2 番目の部分を省略すると、PHP は代わりに最初の部分の結果を配置します。

Martin v. Löwis のベンチマーク コードを使用すると、これはどちらよりも約 25% 高速であると考えられます。

于 2011-01-22T10:47:33.713 に答える