(假设php5)考虑
<?php
$foo = 'some words';
//case 1
print "these are $foo";
//case 2
print "these are {$foo}";
//case 3
print 'these are ' . $foo;
?>
1和2之间有很大差异吗?
如果没有,那么在1/2和3之间呢?
答案 0 :(得分:105)
自2012年1月以来,性能差异为irrelevant,可能更早:
Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds
早期版本的PHP可能有所不同 - 我个人更喜欢单引号加双引号,所以这是一个方便的区别。文章的结论提出了一个很好的观点:
永远不要相信你自己没有伪造的统计数据。
(尽管文章引用了这句话,但最初的讽刺可能是attributed对温斯顿丘吉尔的错误{{3}},由Joseph Goebbels的宣传部门发明,将丘吉尔描绘成一个骗子:
Ich traue keiner Statistik,die ich nichtselbstgefälschthabe。
这松散地转化为“我不相信我没有假装自己的统计数据。”
答案 1 :(得分:43)
嗯,正如所有“现实生活中可能更快”的问题一样,你无法击败现实生活中的考验。
function timeFunc($function, $runs)
{
$times = array();
for ($i = 0; $i < $runs; $i++)
{
$time = microtime();
call_user_func($function);
$times[$i] = microtime() - $time;
}
return array_sum($times) / $runs;
}
function Method1()
{
$foo = 'some words';
for ($i = 0; $i < 10000; $i++)
$t = "these are $foo";
}
function Method2()
{
$foo = 'some words';
for ($i = 0; $i < 10000; $i++)
$t = "these are {$foo}";
}
function Method3()
{
$foo = 'some words';
for ($i = 0; $i < 10000; $i++)
$t = "these are " . $foo;
}
print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";
给它一些运行来分页,然后......
0.0035568
0.0035388
0.0025394
因此,正如预期的那样,插值几乎相同(噪声水平差异,可能是由于插值引擎需要处理的额外字符)。直线连接约为速度的66%,这并不是很大的震撼。插值解析器将查找,无需执行任何操作,然后使用简单的内部字符串concat完成。即使concat很昂贵,内插器仍然必须这样做, 之后所有工作都要解析变量并修剪/复制原始字符串。
Somnath的更新:
我将Method4()添加到上面的实时逻辑中。
function Method4()
{
$foo = 'some words';
for ($i = 0; $i < 10000; $i++)
$t = 'these are ' . $foo;
}
print timeFunc('Method4', 10) . "\n";
Results were:
0.0014739
0.0015574
0.0011955
0.001169
当你只是声明一个字符串而不需要解析那个字符串时,为什么要混淆PHP调试器来解析。我希望你明白我的观点。
答案 2 :(得分:23)
答案 3 :(得分:16)
使用@ Adam的测试
"these are " . $foo
请注意以下内容更快:
'these are ' . $foo;
这是因为有一个双引号“字符串”被评估,其中一个引用的'字符串'就是按原样...
答案 4 :(得分:11)
不要过于专注于尝试在PHP中优化字符串操作。如果您的数据库查询写得不好或者您没有使用任何类型的缓存方案,则连接与插值是没有意义的(在实际性能中)。编写字符串操作,以便以后调试代码很容易,性能差异可以忽略不计。
@uberfuzzy假设这只是一个关于语言细节的问题,我想它没关系。我只是试图在实际应用程序中添加单引号,双引号和heredoc之间的性能,与真实的性能接收器(如数据库查询不佳)相比毫无意义。
答案 5 :(得分:8)
执行时间的任何差异都可以忽略不计。
请参阅
不要在这样的微优化上浪费时间。使用分析器在实际场景中测量应用程序的性能,然后优化实际需要的位置。与在代码中应用微优化相比,优化单个草率数据库查询可能会带来更大的性能提升。
答案 6 :(得分:3)
我似乎记得论坛软件的开发者Vanilla用单引号替换了他的代码中的所有双引号,并注意到合理的性能提升量。
我现在似乎无法追踪到目前讨论的链接。
答案 7 :(得分:3)
连接变量时会有区别......以及你对结果做了什么......如果你正在做的是将它转储到输出,是否输出缓冲。
另外,服务器的内存情况如何?通常,较高级别平台上的内存管理比较低级别的平台更糟糕......
$a = 'parse' . $this;
正在管理用户代码平台级别的内存......
$a = "parse $this";
在php系统代码平台级别管理内存......
所以这些与CPU相关的基准测试并不能说明全部内容。
在尝试同时运行相同模拟1000次的服务器上运行基准测试1000次与运行基准测试1000次...根据应用程序的范围,您可能会得到截然不同的结果。
答案 8 :(得分:2)
双引号可能要慢得多。我从几个地方读到,最好这样做
'parse me '.$i.' times'
大于
"parse me $i times"
虽然我会说第二个给你更多可读代码。
答案 9 :(得分:1)
实际上没有任何区别!查看时间:http://micro-optimization.com/single-vs-double-quotes
答案 10 :(得分:1)
如果您在双引号字符串语法中使用变量,只需添加其他内容:
$foo = "hello {$bar}";
比
快$foo = "hello $bar";
并且这两个都比
快$foo = 'hello' . $bar;
答案 11 :(得分:0)
应该注意的是,当使用带有3个变量的Adam Wright的示例的修改版本时,结果是相反的,前两个函数实际上更快,一致。这是使用CLI上的PHP 7.1:
function timeFunc($function, $runs)
{
$times = array();
for ($i = 0; $i < $runs; $i++)
{
$time = microtime();
call_user_func($function);
@$times[$i] = microtime() - $time;
}
return array_sum($times) / $runs;
}
function Method1()
{
$foo = 'some words';
$bar = 'other words';
$bas = 3;
for ($i = 0; $i < 10000; $i++)
$t = "these are $foo, $bar and $bas";
}
function Method2()
{
$foo = 'some words';
$bar = 'other words';
$bas = 3;
for ($i = 0; $i < 10000; $i++)
$t = "these are {$foo}, {$bar} and {$bas}";
}
function Method3()
{
$foo = 'some words';
$bar = 'other words';
$bas = 3;
for ($i = 0; $i < 10000; $i++)
$t = "these are " . $foo . ", " . $bar . " and " .$bas;
}
print timeFunc('Method1', 10) . "\n";
print timeFunc('Method2', 10) . "\n";
print timeFunc('Method3', 10) . "\n";
我也试过过&#3;&#39;而不只是整数3,但我得到了相同的结果。
$ bas = 3:
0.0016254
0.0015719
0.0019806
使用$ bas =&#39; 3&#39;:
0.0016495
0.0015608
0.0022755
应该注意的是,这些结果差别很大(我得到的变化约为300%),但平均值看起来相对稳定,并且几乎(10个案例中的9个)总是表现出更快的执行速度,使用方法2总是比方法1稍快。
总之:对于单个操作(插值或连接)而言,对于组合操作并不总是如此。
答案 12 :(得分:0)
是的,最初本来是关于PHP5的,但是几个月后又到了PHP8,而今天在我的 PHP 7.4.5 上测试过的最佳选择是使用PHP - Nowdoc(在WIN 10 + Apache上测试过)和CentOs 7 + Apache):
function Method6(){
$k1 = 'AAA';
for($i = 0; $i < 10000; $i ++)$t = <<<'EOF'
K1=
EOF
.$k1.
<<<'EOF'
K2=
EOF
.$k1;
}
此处是方法5(使用 Heredoc 进行串联):
function Method5(){
$k1 = 'AAA';
for($i = 0; $i < 10000; $i ++)$t = <<<EOF
K1= $k1
EOF
.<<<EOF
K2=$k1
EOF;
}
方法1至4在本文开头
在我所有的测试中,“优胜者”是方法6(Newdoc),不是很容易阅读,但是在CPU中非常快,并且曾经使用 @Adam Wright <{1 / strong>。
答案 13 :(得分:0)
我已经使用以下测试用例测试了 php 7.4 和 php 5.4,对我来说仍然有点困惑。
<?php
$start_time = microtime(true);
$result = "";
for ($i = 0; $i < 700000; $i++) {
$result .= "THE STRING APPENDED IS " . $i;
// AND $result .= 'THE STRING APPENDED IS ' . $i;
// AND $result .= "THE STRING APPENDED IS $i";
}
echo $result;
$end_time = microtime(true);
echo "<br><br>";
echo ($end_time - $start_time) . " Seconds";
PHP 7.4 输出
1. "THE STRING APPENDED IS " . $i = 0.16744208335876
2. 'THE STRING APPENDED IS ' . $i = 0.16724419593811
3. "THE STRING APPENDED IS $i" = 0.16815495491028
PHP 5.3 输出
1. "THE STRING APPENDED IS " . $i = 0.27664494514465
2. 'THE STRING APPENDED IS ' . $i = 0.27818703651428
3. "THE STRING APPENDED IS $i" = 0.28839707374573
我已经测试了很多次,在 php 7.4 中,似乎所有 3 个测试用例都多次得到相同的结果,但连接仍然在性能上没有一点优势。
答案 14 :(得分:0)
基于@adam-wright 的回答,我想知道速度差异是否会在没有串联/字符串中没有变量的情况下发生。
== 我的问题...
$array['key']
的调用或设置速度是否比 $array["key"]
!?$var = "some text";
比 $var = 'some text';
慢吗?==我的测试每次都使用新变量以避免使用相同的内存地址:
function getArrDblQuote() {
$start1 = microtime(true);
$array1 = array("key" => "value");
for ($i = 0; $i < 10000000; $i++)
$t1 = $array1["key"];
echo microtime(true) - $start1;
}
function getArrSplQuote() {
$start2 = microtime(true);
$array2 = array('key' => 'value');
for ($j = 0; $j < 10000000; $j++)
$t2 = $array2['key'];
echo microtime(true) - $start2;
}
function setArrDblQuote() {
$start3 = microtime(true);
for ($k = 0; $k < 10000000; $k++)
$array3 = array("key" => "value");
echo microtime(true) - $start3;
}
function setArrSplQuote() {
$start4 = microtime(true);
for ($l = 0; $l < 10000000; $l++)
$array4 = array('key' => 'value');
echo microtime(true) - $start4;
}
function setStrDblQuote() {
$start5 = microtime(true);
for ($m = 0; $m < 10000000; $m++)
$var1 = "value";
echo microtime(true) - $start5;
}
function setStrSplQuote() {
$start6 = microtime(true);
for ($n = 0; $n < 10000000; $n++)
$var2 = 'value';
echo microtime(true) - $start6;
}
print getArrDblQuote() . "\n<br>";
print getArrSplQuote() . "\n<br>";
print setArrDblQuote() . "\n<br>";
print setArrSplQuote() . "\n<br>";
print setStrDblQuote() . "\n<br>";
print setStrSplQuote() . "\n<br>";
== 我的结果:
array 获取 double 引用 2.1978828907013
数组获取单引用2.0163490772247
数组集双引用1.9173440933228
数组获取单引用1.4982950687408
var set double 引用 1.485809803009
var set single 引用 1.3026781082153
== 我的结论!
所以,结果是差异不是很显着。然而,在一个大项目上,我认为它可以有所作为!