【问题标题】:Which is faster between (string)$value and "$value" when casting to a string转换为字符串时 (string)$value 和 "$value" 之间哪个更快
【发布时间】:2019-07-06 04:06:27
【问题描述】:

在 PHP 中,假设 $value = 12345;(一个整数),将 $value 从整数转换为字符串时速度更快;

$value = (string)$value;

$value = "$value";

这是一种绩效衡量问题,专门针对这种情况。感谢您的帮助!

【问题讨论】:

  • 嗯……你测量了吗?我很想知道:)
  • @YvesLeBorg ,我使用这两种方法通过类型转换整数 2 亿次来测量它。平均而言,隐式类型转换比显式类型转换快几百毫秒。
  • @YvesLeBorg,不知道我该怎么做,我仍然想知道是否有人遇到过这样的问题。我正在为这类事情寻找一些推荐的分析工具。如果您有任何建议,请告诉我:)
  • @xSavitar 我为您提供了解决您可能遇到的此类(有趣且非常棘手的)问题的方法要素。
  • @YvesLeBorg,谢谢!我还想用 Zend 解释器和 PHPNG 解释器(分别是 PHP 5 和 PHP 7)来解决这个问题,看看我会有什么不同。 :)

标签: php casting php-7 php-internals


【解决方案1】:

您的问题实际上是关于 php 解释器的功效,以及它如何将php code(您编写的那个)转换为php bytecode(运行并且实际上可能会消耗时间和资源的那个)。如果我把 p01ymath 的实验分解一下:

implicit.php

<?php
$str = 12345;
for($i=0;$i<=200000000;$i++){
    $str2 = "$str";
}

implicit.php 字节码

DarkMax:temp yvesleborg$ php -dvld.active=1 -dvld.verbosity=0 -dvld.exececute=0 implicit.php 
filename:       /Users/yvesleborg/temp/implicit.php
function name:  (null)
number of ops:  14
compiled vars:  !0 = $str, !1 = $i, !2 = $str2
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
 2     0    E >   EXT_STMT                                                 
       1          ASSIGN                                                   !0, 12345
 3     2          EXT_STMT                                                 
       3          ASSIGN                                                   !1, 0
       4        > JMP                                                      ->10
 4     5      >   EXT_STMT                                                 
       6          CAST                                          6  ~5      !0
       7          ASSIGN                                                   !2, ~5
 3     8          POST_INC                                         ~7      !1
       9          FREE                                                     ~7
      10      >   IS_SMALLER_OR_EQUAL                              ~8      !1, 200000000
      11          EXT_STMT                                                 
      12        > JMPNZ                                                    ~8, ->5
 7    13      > > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     4; out0:  10
branch: #  5; line:     4-    3; sop:     5; eop:     9; out0:  10
branch: # 10; line:     3-    3; sop:    10; eop:    12; out0:  13; out1:   5; out2:  13; out3:   5
branch: # 13; line:     7-    7; sop:    13; eop:    13; out0:  -2
path #1: 0, 10, 13, 
path #2: 0, 10, 5, 10, 13, 
path #3: 0, 10, 5, 10, 13, 
path #4: 0, 10, 13, 
path #5: 0, 10, 5, 10, 13, 
path #6: 0, 10, 5, 10, 13,

explicit.php

<?php
$str = 12345;
for($i=0;$i<=200000000;$i++){
    $str2 = (string)$str;
}

explicit.php 字节码

DarkMax:temp yvesleborg$ php -dvld.active=1 -dvld.verbosity=0 -dvld.exececute=0 explicit.php 
filename:       /Users/yvesleborg/temp/explicit.php
function name:  (null)
number of ops:  14
compiled vars:  !0 = $str, !1 = $i, !2 = $str2
line     #* E I O op                           fetch          ext  return  operands
-------------------------------------------------------------------------------------
   2     0  E >   EXT_STMT                                                 
         1        ASSIGN                                                   !0, 12345
   3     2        EXT_STMT                                                 
         3        ASSIGN                                                   !1, 0
         4      > JMP                                                      ->10
   4     5    >   EXT_STMT                                                 
         6        CAST                                          6  ~5      !0
         7        ASSIGN                                                   !2, ~5
   3     8        POST_INC                                         ~7      !1
         9        FREE                                                     ~7
        10    >   IS_SMALLER_OR_EQUAL                              ~8      !1, 200000000
        11        EXT_STMT                                                 
        12      > JMPNZ                                                    ~8, ->5
   7    13    > > RETURN                                                   1

branch: #  0; line:     2-    3; sop:     0; eop:     4; out0:  10
branch: #  5; line:     4-    3; sop:     5; eop:     9; out0:  10
branch: # 10; line:     3-    3; sop:    10; eop:    12; out0:  13; out1:   5; out2:  13; out3:   5
branch: # 13; line:     7-    7; sop:    13; eop:    13; out0:  -2
path #1: 0, 10, 13, 
path #2: 0, 10, 5, 10, 13, 
path #3: 0, 10, 5, 10, 13, 
path #4: 0, 10, 13, 
path #5: 0, 10, 5, 10, 13, 
path #6: 0, 10, 5, 10, 13,

如您所见,两个 sn-ps 都生成完全相同的字节码(任何精心设计的编译器/解释器都期望得到相同的字节码)。因此,上面的实验仅仅测量了引擎在对字节码进行排序、运行时间以及在其上运行的盒子(芯片组)上的实际运行时性能。

要真正回答你自己的问题,你必须思考一个更棘手的问题:

在什么情况下显式转换会产生与隐式转换不同的字节码。

如果您发现此类情况,请进行测试以衡量它们各自的性能。

如果你想完成这个任务,你需要pecl vld 组件。你可以按照这个interesting post来熟悉vld(一定要检查pecl,并为你的被测php编译器安装合适的版本)

【讨论】:

  • 非常感谢您的回复。非常足智多谋,对于帖子的链接也是如此,我会阅读它。 :) 随着时间的推移,我愿意越来越多地探索这个任务,非常欢迎来自 SO 的反馈,以便为那些认为这个任务也有用的人拓宽思路。
【解决方案2】:

有趣的问题。我对测试这些东西完全是愚蠢的,但我还是这样做了。看到你的问题后,我想到了检查哪个更快。

所以这个想法很简单,我将创建一个脚本来使用implicitexplicit 方法2亿次来输入一个整数,看看是否有区别。 p>

我发现,速度没有太大差别。这是我为执行测试而编写的脚本。

<?php
$str = 12345;

$startTimeExplicit = microtime(true);
for($i=0;$i<=200000000;$i++){
    $str2 = (string)$str;
}
$endTimeExplicit = microtime(true);
$explicit = round($endTimeExplicit-$startTimeExplicit,6);

$startTimeImplicit = microtime(true);
for($i=0;$i<=200000000;$i++){
    $str2 = "$str";
}
$endTimeImplicit = microtime(true);
$implicit = round($endTimeImplicit-$startTimeImplicit,6);

echo "Average time (Implicit type casting): ".$implicit."<br>";
echo "Average time (Explicit type casting): ".$explicit."<br>";

?>

这是我多次执行此脚本后得到的结果。

Average time (Implicit type casting): 14.815689
Average time (Explicit type casting): 14.614734

Average time (Implicit type casting): 14.56812
Average time (Explicit type casting): 15.190028

Average time (Implicit type casting): 14.649186
Average time (Explicit type casting): 15.587608

Average time (Implicit type casting): 15.522457
Average time (Explicit type casting): 15.566786

Average time (Implicit type casting): 15.235483
Average time (Explicit type casting): 15.333145

Average time (Implicit type casting): 15.972657
Average time (Explicit type casting): 16.161957

如您所见,它们都同样快。有时隐式类型转换快几百毫秒,有时是显式的。但平均而言,你看不出有什么不同。

【讨论】:

  • 谢谢!如果可能的话,我会使用分析工具而不是普通的 PHP 脚本来解决这个问题,但非常感谢!
  • 其实你测的就是这个实验的结果,没有别的,可能(也可能与OP的任务无关)。如果……说……实际投射时间是与循环相比的背景噪音。您将无法确认 There is no much difference in speed。直到你查看了这两种方法的字节码(可能还有实现指令的代码),你才能设计一个有意义的实验。 .02
  • @YvesLeBorg 是的,我知道这个程序中没有噪音可以产生影响,它会在实际程序中存在。但我根据问题中给出的输入进行了测试。
猜你喜欢
  • 2019-09-08
  • 1970-01-01
  • 1970-01-01
  • 2016-12-14
  • 1970-01-01
  • 2018-09-13
  • 2014-06-07
  • 2010-10-08
相关资源
最近更新 更多