哪种结构更快?

时间:2011-01-22 09:54:07

标签: php performance opcode

哪种结构更快:

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

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

所有变量都是本地变量。

多重复用,加法,减法和除法的速度是否不同?

更新

以下是一些澄清:

  1. 这是一个从头开始编写速度优化代码的理论问题。不是“搜索瓶颈”。
  2. 我可以自己测量代码速度。但这不是关于使用microtime()的家庭作业的问题。这是一个关于PHP解释器是如何工作的问题(我试图通过自己挖掘Google来解决这个问题,但是这个问题很简单)。
  3. 而且 - 我自己做了测量,有点困惑。 $ a,$ b和$ c的不同起始值(零,负,正,整数和浮点的组合)在结构之间产生不同的结果。所以我很困惑。
  4. BoltClock为我提供了有用的信息,但是user576875通过发布操作码解码器链接来创造我的一天!他的答案也包含对我问题的直接回答。谢谢!

3 个答案:

答案 0 :(得分:10)

如果你有PHP 5.3,那就更快了:

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

这与$a = $b * $c ? $b * $c : 0;相同,但$a*$b计算仅执行一次。此外,它不会像您的第二个解决方案那样执行其他分配。

使用Martinv.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扩展程序生成的。

答案 1 :(得分: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版本,结果可能会再次改变。

答案 2 :(得分:0)

你的两段代码各有一个缺点。一个人做了额外的任务;另一个做了额外的数学运算。最好不要这样做,使用PHP 5.3中的三元运算符,你可以:

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

省略三元的第二部分会导致PHP将第一部分的结果放在那里。

使用Martinv.Löwis的基准测试代码,我认为这比任何一个快25%。