我正在修改一些代码,原作者使用数组构建了一个网页,如下所示:
$output[]=$stuff_from_database;
$output[]='more stuff';
// etc
echo join('',$output);
有人能想到这样做更好的原因吗(反之亦然):
$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;
我正在修改一些代码,原作者使用数组构建了一个网页,如下所示:
$output[]=$stuff_from_database;
$output[]='more stuff';
// etc
echo join('',$output);
有人能想到这样做更好的原因吗(反之亦然):
$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $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
再次偏离主题一点(不是非常远),但是如果你想在输出的数组项之间放置一些内容,那么如果只有几行要连接,则join(',',$ output)可以轻松快捷地完成。这样写起来更容易,避免了检查列表末尾(您不希望出现尾随“,”)。
对于程序员而言,由于它的成本是CPU周期的1000倍以上,所以我通常会将其放到join中,如果它不会每秒运行10,000次以上。
像这样进行后编码微优化很少值得花费时间来节省CPU时间。
这个话题有点偏离主题,但是
$output =$stuff_from_database;
$output .='more stuff';
// etc
echo $output;
echo = $stuff_from_database;
echo 'more stuff';
ob_start();
echo = $stuff_from_database;
echo 'more stuff';
$output = ob_get_contents();
ob_end_clean();
由于输出缓冲区的工作方式等原因,这是构建字符串最快的方法。显然,只有在真正需要优化字符串构建时才会这样做,因为它不美观且不便于代码的易读性。而且每个人都知道,“过早地进行优化是万恶之源”。
<!-- 已编辑的先前评论 -->
看起来我的代码有错误,所以我在执行无操作并忘记检查。
与之前的测试和阅读有关主题的博客相反,以下结论实际上是(经过测试)不正确,至少对于我可以排列的所有上述代码变体。
在实际测试中,Sprintf是最慢的,而插值是最快的
PHP 5.2.6-pl7-gentoo (cli) (built: Sep 21 2008 13:43:03) 版权所有(c)1997-2008 PHP Group Zend Engine v2.2.0,版权所有(c)1998-2008 Zend Technologies Xdebug v2.0.3,版权所有(c)2002-2007,作者Derick Rethans
可能是因为我的设置有条件限制,但这仍然很奇怪。 :/
我认为最快的方法是使用回声。虽然这种方法不够美观,而且可能并没有足够的速度优势来抵消可读性上的成本。
echo $stuff_from_database
, 'more stuff'
, 'yet more'
// etc
, 'last stuff';
底部将重复重新分配 $output 字符串,而我认为顶部只会将每个片段存储在数组中,然后在最后将它们全部连接起来。因此,原始示例可能会因此变得更快。如果这不是性能敏感的话,我可能会选择追加而不是连接。
implode()
或join()
一起使用,PHP能够更好地进行优化。它会遍历列表中的所有字符串,计算长度并分配所需空间并填充空间。与".="相比,它必须不断地free()
和malloc()
字符串的空间。这部分代码不太注重性能;它用于在低流量网站上格式化和显示用户的购物车信息。此外,数组(或字符串)每次都是从头开始构建的,没有必要寻找特定元素。听起来数组有点更有效率,但我想对于这种用途来说也无所谓了。感谢您提供的所有信息!
虽然已经有人提到过,但我认为一个明确的答案会更有帮助。
原始程序员编写代码时认为这样更快。实际上,在 PHP 4 下,特别是对于较大的字符串,确实更快。
for ($prod in $cart)
{
$prod->printHTML();
}
或者类似的方式。这样,代码就变得更加清晰。当然,这是建立在你有良好的对象化代码的前提下,而不是像我们公司一样整个代码混乱无章(正在进行替换)。