(假设 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 之间呢?
(假设 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 之间呢?
至少从 2012 年 1 月开始,性能差异就变得无关紧要了,而且可能更早:
Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds
PHP 的早期版本可能有所不同——我个人更喜欢单引号而不是双引号,所以这是一个方便的区别。文章的结论提出了一个很好的观点:
永远不要相信不是你自己伪造的统计数据。
(虽然文章引用了这句话,但最初的俏皮话很可能被错误地归因于温斯顿丘吉尔,由约瑟夫戈培尔的宣传部发明,将丘吉尔描绘成一个骗子:
Ich traue keiner Statistik, die ich nicht selbst gefälscht habe。
这大致翻译为“我不相信我没有伪造自己的统计数据。”)
好吧,就像所有“现实生活中什么可能更快”的问题一样,你无法通过现实生活中的测试。
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 很昂贵,插值器仍然必须这样做,毕竟解析变量和修剪/复制原始字符串的工作。
索姆纳特的更新:
我将 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 调试器来解析。我希望你明白我的意思。
使用@Adam 的测试
"these are " . $foo
请注意,以下内容甚至更快:
'these are ' . $foo;
这是由于这样一个事实,即双引号“字符串”被评估,其中单引号“字符串”按原样...
不要太着迷于尝试优化 PHP 中的字符串操作。如果您的数据库查询写得不好或者您没有使用任何类型的缓存方案,则连接与插值是没有意义的(在现实世界的性能中)。以这样一种方式编写字符串操作,以便以后调试代码很容易,性能差异可以忽略不计。
@uberfuzzy 假设这只是一个关于语言细节的问题,我想这很好。我只是想补充一点,与实际性能下降(例如糟糕的数据库查询)相比,比较现实世界应用程序中单引号、双引号和heredoc 之间的性能毫无意义。
执行时间的任何差异都可以忽略不计。
请参见
不要在这样的微优化上浪费时间。使用分析器来衡量您的应用程序在真实场景中的性能,然后在真正需要的地方进行优化。与在整个代码中应用微优化相比,优化单个草率的 DB 查询可能会带来更大的性能改进。
连接变量时存在差异......以及您对结果所做的事情......如果您正在做的是将其转储到输出,是否正在输出缓冲。
另外,服务器的内存情况如何?通常,高级平台上的内存管理比低级平台上的更差......
$a = 'parse' . $this;
正在用户代码平台级别管理内存...
$a = "parse $this";
正在php系统代码平台级别管理内存...
所以这些与 CPU 相关的基准测试并不能说明全部情况。
运行基准测试 1000 次与在尝试同时运行相同模拟 1000 次的服务器上运行基准测试 1000 次...根据应用程序的范围,您可能会得到截然不同的结果。
我似乎记得论坛软件的开发者 Vanilla 用单引号替换了他代码中的所有双引号,并注意到性能有合理的提升。
不过,我目前似乎无法找到讨论的链接。
如果您在双引号字符串语法中使用变量,只需添加其他内容:
$foo = "hello {$bar}";
比
$foo = "hello $bar";
这两个都比
$foo = 'hello' . $bar;
双引号可能会慢得多。我从几个地方读到最好这样做
'parse me '.$i.' times'
比
"parse me $i times"
虽然我会说第二个给你更多可读的代码。
几乎没有任何区别!查看时间: http: //micro-optimization.com/single-vs-double-quotes
应该注意的是,当使用 Adam Wright 的示例的修改版本和 3 个变量时,结果是相反的,前两个函数实际上更快、更一致。这是 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' 而不是整数 3,但我得到了同样的结果。
使用 $bas = 3:
0.0016254
0.0015719
0.0019806
使用 $bas = '3':
0.0016495
0.0015608
0.0022755
应该注意的是,这些结果差异很大(我得到大约 300% 的变化),但平均值似乎相对稳定,几乎(10 个案例中有 9 个)总是显示前两种方法的执行速度更快,方法 2 总是略快于方法1。
总而言之:对于 1 个单一操作(无论是插值还是串联)正确的情况对于组合操作并不总是正确的。
是的,最初这是关于 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 中速度非常快,并且曾经使用过function timeFunc($function)
@Adam Wright的函数。
我已经用以下测试用例测试了 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 个测试用例都多次得到相同的结果,但串联在性能上仍然没有一点优势。
根据@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>";
== 我的结果:
数组获取双引号2.1978828907013
数组获取单引号2.0163490772247
数组集双引号1.9173440933228
数组获取单引号1.4982950687408
var 设置双引号1.485809803009
var 设置单引号1.3026781082153
==我的结论!
所以,结果是差异不是很显着。但是,在一个大项目上,我认为它可以有所作为!