PHP的:输出[]瓦特/加入VS $输出。=

时间:2020-03-06 14:30:29  来源:igfitidea点击:

我正在修改一些代码,其中原始作者因此使用数组构建了一个网页:

$output[]=$stuff_from_database;
 $output[]='more stuff';
 // etc
 echo join('',$output);

谁能想到一个比以下更适合(反之亦然)的原因:

$output =$stuff_from_database;
 $output .='more stuff';
 // etc
 echo $output;

解决方案

底部将重复地重新分配$ output字符串,而我相信顶部将只将每个片段存储在一个数组中,然后在最后将它们全部加入。结果,原始示例可能会变得更快。如果这对性能不敏感,那么我可能会追加而不是加入。

它可能是由某个人编写的,该人来自于字符串是不可变的,因此串联是昂贵的。如以下测试所示,PHP不是其中之一。因此,第二种方法是性能明智的,更好的方法。我可以想到使用第一种方法的唯一其他原因是能够用另一种方法替换数组的某些部分,但这意味着要跟踪未指定的索引。

~$ cat join.php
<?php

for ($i=0;$i<50000;$i++) {
$output[] = "HI $i\n";
}

echo join('',$output);
?>

~$ time for i in `seq 100`; do php join.php >> outjoin ; done

real    0m19.145s
user    0m12.045s
sys     0m3.216s

~$ cat dot.php
<?php

for ($i=0;$i<50000;$i++) {
$output.= "HI $i\n";
}

echo $output;
?>

~$ time for i in `seq 100`; do php dot.php >> outdot ; done

real    0m15.530s
user    0m8.985s
sys     0m2.260s

如果与implode()或者join()结合使用,PHP可以更好地对其进行优化。它遍历列表中的所有字符串,计算长度并分配所需的空间并填充该空间。与"。="相比,它必须不断地free()malloc()字符串的空间。

<!-已编辑以前的注释->

看来我的代码有错误,所以我没有操作,却忘了检查。

对于以前的测试来说,它似乎是Contary,并且阅读了有关该主题的以前的博客,
至少对于我可以置换的上述代码的所有变体,以下结论实际上(经测试)是不正确的。

  • UNTRUE:字符串插值比字符串串联慢。 (!)
  • 错误:SprintF最快。

在实际测试中,Sprintf速度最慢,插值速度最快

PHP 5.2.6-pl7-gentoo (cli) (built: Sep 21 2008 13:43:03) 
Copyright (c) 1997-2008 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2008 Zend Technologies
    with Xdebug v2.0.3, Copyright (c) 2002-2007, by Derick Rethans

这可能是我设置的条件,但仍然很奇怪。 :/

这有点题外话,但是

$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;

远慢于:

echo = $stuff_from_database;
echo 'more stuff';

实际上,在PHP中构建字符串的最快方法是:

ob_start();
echo = $stuff_from_database;
echo 'more stuff';
$output = ob_get_contents();
ob_end_clean();

由于输出缓冲区的工作方式等原因,这是构建字符串的最快方法。显然,只有在确实需要优化sting构建的情况下才这样做,因为它很丑陋并且不会导致代码易于阅读。每个人都知道"过早的优化是万恶之源"。

再次,离主题有点远(不是很远),但是如果我们打算在要输出的数组项之间放置一些内容,那么如果只有几行要连接,join(',',$ output)可以做到它足够容易和迅速。这样会更容易编写,并且避免了必须检查列表的末尾(我们不希望在末尾加上',')。

对于程序员来说,因为它比cpu周期贵1000倍左右,所以如果不打算每秒运行10,0000次以上,我通常会将其放入连接中。

就节省的时间与节省的CPU时间而言,像这样的后期编码微优化非常不值得。

我认为最快的方法是回声。它不是那么漂亮,可能还不够快,不足以值得在可读性方面付出代价。

echo $stuff_from_database
   , 'more stuff'
   , 'yet more'
   // etc
   , 'last stuff';

这部分代码对性能不敏感。它用于在低流量的网站上格式化和显示用户的购物车信息。同样,每次都从头开始构建数组(或者字符串),无需寻址或者搜索特定元素。听起来数组效率更高,但是我想这两种用法都没有关系。感谢我们提供所有信息!

如果我们要生成列表(例如购物车),则应该具有一些代码,这些代码将从数据库中提取的每个条目生成HTML。

for ($prod in $cart)
{
  $prod->printHTML();
}

或者类似的东西。这样,代码就变得更加整洁。当然,这是假设对象代码不错,而不是像我公司那样(并且正在替换)整个笨拙的混乱。

已经有人说过,但是我认为一个不同的答案会有所帮助。

最初的程序员是这样写的,因为他认为它更快。实际上,在PHP 4下,它确实更快,尤其是对于大字符串。