问题
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