哪个施工速度更快?

发布于 2024-10-13 15:12:22 字数 531 浏览 3 评论 0原文

哪个构造更快:

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

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

所有变量都是局部变量。

乘法、加法、减法和除法的速度是否不同?

更新:

这里有一些澄清:

  1. 这是一个关于从头开始编写速度优化代码的理论问题。不是“寻找瓶颈”。
  2. 我可以自己测量代码速度。但这不是关于使用 microtime() 的作业问题。这是一个关于 PHP 解释器如何工作的问题(我试图通过自己挖掘谷歌来弄清楚,但不完整)。
  3. 而且 - 我自己测量了一下,有点困惑。 $a、$b 和 $c 的不同起始值(零、负数、正数、整数和浮点数的组合)在构造之间产生不同的结果。所以我很困惑。

BoltClock 为我提供了有用的信息,但 user576875 通过发布操作码解码器的链接让我很开心!他的回答也包含了对我的问题的直接回答。谢谢!

Which construction is faster:

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

or

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

All variables are local ones.

Does speed differs for mulitplication, addition, substraction and division?

Update:

Here's some clarification:

  1. This is a theoretical question about writing speed-optimized code from scratch. Not about "searching bottlenecks".
  2. I can measure code speed by myself. But it's was not a question about homework of using microtime(). It was a question about how PHP-interpreter works (what I tried to figure out by digging google myself but was unseccusfull).
  3. Moreover - I did measuring with myself and was a little confused. Different starting values of $a, $b and $c (combinations of zeros, negative, positive, integer and floats) produce different results between constructions. So I was confused.

BoltClock provide me usefull info but user576875 made my day by posting a link to opcode decoder! His answer contains also direct answer to my question. Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

青朷 2024-10-20 15:12:22

如果您有 PHP 5.3,这会更快:

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

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

使用 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操作码:

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 扩展名。

If you have PHP 5.3, this is faster:

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

This is the same as $a = $b * $c ? $b * $c : 0;, but the $a*$b calcultation is done only once. Also, it doesn't do additional assignments as in your second solution.

Using Martin v. Löwis's benchmark script I get the following times:

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

Now these are micro-optimizations, so there is probably many ways of optimizing your code before doing this :)

If it is not the case, you may also want to compare generated PHP OP codes:

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

These OP code listings was generated by the VLD extension.

沉默的熊 2024-10-20 15:12:22
<?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版本,结果可能会再次改变。

<?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();
?>

On my system (PHP 5.3.3, Linux, Core i7 2.8GHz), I get

1.593521
1.512892

So the separate assignment is slightly faster. For addition, (+ instead of *), I get the reverse result:

1.386522
1.450358

So you really need to measure these on your own system - with a different PHP version, the outcome may change again.

白昼 2024-10-20 15:12:22

您的两段代码各有一个缺点。一个人做一项额外的作业;另一个进行额外的数学运算。最好两者都不做,使用 PHP 5.3 中的三元运算符,您可以:

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

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

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

Your two pieces of code have a drawback each. One does an additional assignment; the other does an additional mathematical operation. Best would be to do neither, which, with the ternary operator in PHP 5.3, you can:

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

Omitting the second part of the ternary causes PHP to put the result of the first part there instead.

Using Martin v. Löwis's benchmarking code, I reckon this is about 25% faster than either.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文