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

时间:2020-03-05 18:40:09  来源:igfitidea点击:

(假设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之间呢?

解决方案

回答

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

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调试器来解析。希望你明白我的意思。

回答

@Adam的测试使用

"these are " . $foo

请注意,以下操作甚至更快:

'these are ' . $foo;

这是由于以下事实:对双引号的"字符串"进行了评估,其中单引号的"字符串"按原样被使用...

回答

不要太着迷于尝试优化PHP中的字符串操作。如果数据库查询写得不好或者我们没有使用任何类型的缓存方案,那么串联与插值之间就没有意义了(在现实世界中的表现)。以这样的方式编写字符串操作,以便以后调试代码变得容易,而性能差异可以忽略不计。

@uberfuzzy假设这只是有关语言细节的问题,我想这很好。我只是想增加一种对话,即与真实的性能接收器(例如不良的数据库查询)相比,在现实应用程序中比较单引号,双引号和Heredoc之间的性能毫无意义。

回答

至少从2012年1月起,性能差异就没有关系了,并且可能更早:

Single quotes: 0.061846971511841 seconds
Double quotes: 0.061599016189575 seconds

PHP的早期版本可能有所不同,我个人更喜欢单引号而不是双引号,因此这是一个方便的区别。文章的结论很好地说明了这一点:

Never trust a statistic you didn’t forge yourself.

(尽管文章引用了这个短语,但最初的讽刺可能是错误地归因于约瑟夫·戈培尔(Joseph Goebbels)的宣传部发明的温斯顿·丘吉尔(Winston Churchill),他将丘吉尔描绘成骗子:

Ich traue keiner Statistik, die ich nicht selbst gef?lscht habe.

这可以粗略地解释为:"我不相信自己没有伪造自己的统计数据。")

回答

我似乎还记得论坛软件的开发人员Vanilla用单引号替换了他代码中的所有双引号,并注意到性能有合理的提高。

不过,我目前似乎无法找到该讨论的链接。

回答

实时基准测试:

http://phpbench.com/

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

回答

双引号可能会慢得多。我从几个地方读到,这样做更好

'parse me '.$i.' times'

"parse me $i times"

尽管我会说第二个代码为我们提供了更具可读性的代码。

回答

在连接变量时,以及在对结果进行处理时,以及在将其转储到输出,输出缓冲是否存在时,都有所不同。

另外,服务器的内存状况如何?通常,较高级别的平台上的内存管理比较低级别的平台上的内存管理差。

$a = 'parse' . $this;

正在用户代码平台级别管理内存...

$a = "parse $this";

正在php系统代码平台级别管理内存...

因此,这些与CPU相关的基准测试无法说明全部情况。

在尝试同时运行同一模拟1000次的服务器上运行1000次基准测试与运行1000次基准测试...根据应用程序的范围,我们可能会获得截然不同的结果。