我正在修改一些代码,其中原始作者通过使用数组来构建网页:
$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
这有点离题,但是
$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 时间而言,像这样的后编码微优化很少值得。
<!-- 已编辑以前的评论 -->
看来我的代码中有错误,所以我没有执行任何操作并忘记检查。
这似乎与之前的测试相反,并且阅读之前关于该主题的博客,以下结论实际上(经过测试)至少对于我可以置换的上述代码的所有变体都是不正确的。
实际测试中,Sprintf最慢 ,插值最快
PHP 5.2.6-pl7-gentoo (cli) (内置: Sep 21 2008 13:43:03) 版权所有 (c) 1997-2008 PHP 集团 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';
如果加入implode()
or join()
,PHP 能够更好地优化它。它遍历列表中的所有字符串,计算长度并分配所需的空间并填充空间。与“。=”相比,它必须不断地free()
为malloc()
字符串留出空间。
已经说过了,但我认为一个明确的答案会有所帮助。
最初的程序员是这样写的,因为他认为这样更快。事实上,在 PHP 4 下,它确实更快,尤其是对于大字符串。
底部将重复重新分配 $output 字符串,而我相信顶部只会将每个部分存储在一个数组中,然后在最后将它们全部连接起来。结果,原始示例最终可能会更快。如果这对性能不敏感,那么我可能会追加,而不是加入。
这部分代码对性能不敏感;它用于在低流量网站上格式化和显示用户的购物车信息。此外,数组(或字符串)每次都是从头开始构建的,无需寻址或搜索特定元素。听起来数组的效率更高一些,但我想这两种方式都无关紧要。感谢您提供所有信息!
如果您正在生成一个列表(例如购物车),您应该有一些代码可以从从数据库中获取的每个条目生成 HTML。
for ($prod in $cart)
{
$prod->printHTML();
}
或类似的东西。这样,代码就变得干净多了。当然,这假设您有很好的对象代码,而不是像我的公司那样(并且正在替换)一团糟。