在php5中使用内联字符串与串联的速度差异?

Ube*_*zzy 46 php optimization performance

(假设php5)考虑

<?php

    $foo = 'some words';

    //case 1
    print "these are $foo";

    //case 2
    print "these are {$foo}";

    //case 3
    print 'these are ' . $foo;
?>
Run Code Online (Sandbox Code Playgroud)

1和2之间有很大差异吗?

如果没有,那么在1/2和3之间呢?

Pao*_*ino 105

自2012年1月以来,性能差异无关紧要,可能更早:

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds
Run Code Online (Sandbox Code Playgroud)

早期版本的PHP可能有所不同 - 我个人更喜欢单引号加双引号,所以这是一个方便的区别.该文的结论提出了一个很好的观点:

永远不要相信你自己没有伪造的统计数据.

(虽然文章引用了这句话,但最初的讽刺可能错误地归因于约瑟夫·戈培尔的宣传部发明的温斯顿·丘吉尔,将丘吉尔描绘成一个骗子:

Ich traue keiner Statistik,die ich nichtselbstgefälschthabe.

这松散地转化为"我不相信我没有假装自己的统计数据.")

  • 而且,最重要的是,通过使用更少的像素,您可以减少温室气体排放. (151认同)
  • 实际上,由于更快的计算意味着更少的CPU时间意味着消耗更少的瓦特,单引号确实可以减少温室气体排放. (14认同)
  • @Paolo Begantino:你真的有这方面的证据吗?http://www.phpbench.com/每次加载时都尊重你. (14认同)
  • 请注意,即使您使用单引号字符串,PHP仍然会解析其中的每个字符,以查找转义序列等.PHP也在解析整个_file_,所以充其量,您仍然在查看O( n)字符串的长度. (5认同)
  • 这不是一个编译时检查吗? (4认同)
  • "这不是一个编译时检查吗?" - 没人为什么会这样.它是一种脚本语言,因此编译时间是运行时间. (4认同)

Ada*_*ght 44

好吧,就像所有"现实生活中可能更快"的问题一样,你无法击败现实生活中的考验.

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";
Run Code Online (Sandbox Code Playgroud)

给它几个运行页面,然后......

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
Run Code Online (Sandbox Code Playgroud)

当你只是声明一个字符串而不需要解析那个字符串时,为什么要混淆PHP调试器来解析.我希望你明白我的观点.

  • 当然,你无法击败现实生活中的考试.但这种人造弗兰肯斯坦与现实生活条件毫无共同之处. (15认同)
  • 那些试图在 PHP5+ 上重现这些结果的怀疑论者(如我 ;-) 将 `microtime()` 调用更改为 `microtime(true)` - 您希望时间作为浮点数,而不是某种奇怪的字符串。 (2认同)
  • 添加了用于字符串处理的 Method4()。我认为 PHP 处理现在变得更快了。@亚当赖特 (2认同)
  • 你好。您的比较假设字符串中只有一个变量实例。请参阅 http://stackoverflow.com/a/31312867/2893496 (2认同)

Mik*_*e B 23

实时基准测试:

http://phpbench.com/

将变量与单引号和双引号连接时,实际上存在细微差别.


Pie*_*ing 16

@ Adam的测试用过

"these are " . $foo
Run Code Online (Sandbox Code Playgroud)

请注意以下内容更快:

'these are ' . $foo;
Run Code Online (Sandbox Code Playgroud)

这是因为有一个双引号"字符串"得到评估,其中一个引用的"字符串"就是按原样...

  • 我刚刚做了一些快速测试,这两者之间没有多少节省 - 当然远不及将插值更改为串联 - 但单引号更快。 (2认同)

Jak*_*raw 11

不要试图在PHP中优化字符串操作.如果您的数据库查询写得不好或者您没有使用任何类型的缓存方案,则连接与插值是没有意义的(在实际性能中).编写字符串操作,以便以后调试代码很容易,性能差异可以忽略不计.

@uberfuzzy假设这只是一个关于语言细节的问题,我想它没关系.我只是试图在真实性能接收器(例如糟糕的数据库查询)中比较实际应用程序中单引号,双引号和heredoc之间的性能比较无意义的对话.


Gor*_*don 8

执行时间的任何差异都可以忽略不计.

请参阅

不要在这样的微优化上浪费时间.使用分析器在实际场景中测量应用程序的性能,然后优化实际需要的位置.与在整个代码中应用微优化相比,优化单个草率数据库查询可能会带来更大的性能提升.