【发布时间】:2011-03-26 16:53:17
【问题描述】:
首先,我知道在 90% 的应用程序中,性能差异完全无关紧要,但我只需要知道哪个是更快的构造。那和...
目前在网上获得的信息令人困惑。很多人说 foreach 不好,但从技术上讲,它应该更快,因为它可以简化使用迭代器编写数组遍历的过程。迭代器,再次被认为更快,但在 PHP 中也显然非常慢(或者这不是 PHP 的东西?)。我说的是数组函数:next() prev() reset() 等等,如果它们是偶数函数而不是那些看起来像函数的 PHP 语言特性之一。
缩小一点:我对以超过 1 的步数遍历数组并不感兴趣(也没有负步数,即反向迭代)。我也对往返任意点的遍历不感兴趣,只是长度为 0。我也没有看到定期操作超过 1000 个键的数组,但我确实看到一个数组在应用程序的逻辑中被多次遍历!同样对于操作,主要是字符串操作和回显。
这里有几个参考网站:
http://www.phpbench.com/
http://www.php.lt/benchmark/phpbench.php
我到处听到的:
-
foreach很慢,因此for/while更快 - PHPs
foreach复制它迭代的数组;为了使其更快,您需要使用引用 - 这样的代码:
$key = array_keys($aHash); $size = sizeOf($key); <br>for ($i=0; $i < $size; $i++)比foreach快
这是我的问题。我写了这个测试脚本:http://pastebin.com/1ZgK07US,无论我运行多少次,我都会得到这样的结果:
foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801
简而言之:
-
foreach比foreach快 -
foreach比for快 -
对于哈希表,
foreach比for快
谁能解释一下?
- 我做错了吗?
- PHP foreach 引用的东西真的有影响吗?我的意思是如果你通过引用它为什么不复制它?
- foreach 语句的等效迭代器代码是什么?我在网上看到过一些,但每次我测试它们的时间都差了;我还测试了一些简单的迭代器构造,但似乎从来没有得到过像样的结果——PHP 中的数组迭代器是不是很糟糕?
- 除了 FOR/FOREACH(和 WHILE)之外,还有更快的方法/方法/构造来迭代数组吗?
PHP 版本 5.3.0
编辑:回答 在人们的帮助下,我能够拼凑出所有问题的答案。我将在这里总结它们:
- “我做错了吗?” 共识似乎是:是的,我不能在基准测试中使用 echo。就个人而言,我仍然看不到 echo 是如何具有随机执行时间的某个函数,或者任何其他函数有何不同——而且该脚本生成与 foreach 完全相同的结果的能力比一切都好虽然只是解释“你正在使用回声”(我应该一直使用什么)。但是,我承认测试应该用更好的方法来完成。虽然没有想到一个理想的折衷方案。
- “PHP foreach 引用的东西真的有影响吗?我的意思是如果你通过引用它为什么不复制它?” ircmaxell 表明是的,进一步的测试似乎证明在大多数情况下引用应该更快——尽管考虑到我上面的 sn-p 代码,但绝对不是全部。我接受这个问题可能太不直观,无法在这样的级别上烦恼,并且需要一些极端的东西,例如反编译才能实际确定哪种情况更适合每种情况。
- “foreach 语句的等效迭代器代码是什么;我在网上看到了一些,但每次我测试它们时时间都差了;我还测试了一些简单的迭代器构造,但似乎从未得到甚至不错的结果——PHP 中的数组迭代器真的很糟糕吗?” ircmaxell 提供了下面的答案;虽然代码可能只对 PHP 版本 >= 5 有效
- “除了 FOR/FOREACH(和 WHILE)之外,还有更快的方法/方法/构造来迭代数组吗?” 感谢 Gordon 的回答。在 PHP5 中使用新的数据类型应该可以提高性能或提高内存(根据您的情况,这两者都可能是可取的)。虽然在速度方面很多新类型的数组似乎并不比 array() 好,但 splpriorityqueue 和 splobjectstorage 似乎确实要快得多。戈登提供的链接:http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/
感谢所有试图提供帮助的人。
对于任何简单的遍历,我可能会坚持使用 foreach(非参考版本)。
【问题讨论】:
-
基准测试规则 2.71:不要重复基准测试。
-
foreach with reference 必须以 for with reference 为基准。你有一个有缺陷的结论。即使在 do-while 循环中,任何引用的使用显然都会比没有引用的情况慢。
-
由于这是针对 php 5.3 的,您可能还需要考虑测试新的 Spl 数据类型与数组。或者看看这里:matthewturland.com/2010/05/20/new-spl-features-in-php-5-3
-
@ Mchl:我运行了几次,得到了相同的结果——如果 echo 破坏了基准,那么我不应该得到完全随机的结果吗?我也想迭代一些东西并输出它,所以 echo 实际上对我来说真的很重要;如果在回显时 foreach 更快,那么这是我应该使用 foreach 的一大块代码。 @ stillstanding:我所听到的基本上是“foreach 中的参考使(总是)更快,总是参考参考”,这就是我这样测试的原因——我对与其他参考循环的比较并不感兴趣
-
这些空洞的问题自然应该被禁止。以及那个欺骗性的 phpbench 网站
标签: php arrays performance foreach for-loop