Which is faster between (string)$value and “$value” when casting to a string

放肆的年华 提交于 2019-12-12 20:17:33

问题


In PHP, assuming $value = 12345;(an integer), which is faster when casting $value from an integer to a string;

$value = (string)$value;

or

$value = "$value";

This is a kind of performance measure question and specifically for this case. Thanks for your help!


回答1:


Your question is really about the efficacy of the php interpreter, and how it converts php code (the one you write) to php bytecode (the one that runs and may actually consume time and resources). If i take p01ymath's experiment, and decompose it:

implicit.php

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

implicit.php bytecode

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 bytecode

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,

as you can see, both snippets produce exactly the same bytecode (which you would expect from any well-crafted compiler/interpreter). Thus, the experiment above merely measures the actual run-time performance of the engine as it is sequencing the bytecode, at the time it was run, and on the box (chipset) it was run on.

To really answer your own question, you have to ponder the trickier question:

Under which circumstances does an explicit cast produce different bytecode from an implicit cast.

and if you find such circumstances, instrument a test to measure their respective performance.

If you want to pursue this quest, you will need the pecl vld component. You can follow this interesting post to get familiar with vld (be sure to check on pecl, and install the appropriate version for your php compiler under test)




回答2:


Interesting question. I am totally dumb about testing these kind of things but I do it anyways. After seeing your question, I got an idea to check which one is faster.

So the idea is simple, I will just create a script to type cast an integer using both implicit and explicit methods 200 million times to see if there is a difference.

What I found out is, There is no much difference in speed. Here is the script I made to perform the tests.

<?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>";

?>

And here are the results I got after executing this script multiple times.

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

As you can see, both of them are equally fast. Sometimes Implicit type casting is few hundred milliseconds fast and sometimes Explicit. But on Average, You can't see much difference.



来源:https://stackoverflow.com/questions/54651290/which-is-faster-between-stringvalue-and-value-when-casting-to-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!