出于性能VS在PHP FOREACH [英] Performance of FOR vs FOREACH in PHP

查看:201
本文介绍了出于性能VS在PHP FOREACH的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

首先,我了解90%的应用程序的性能差异是完全不相干的,但我只需要知道这是更快的构建。这和...

First of all, I understand in 90% of applications the performance difference is completely irrelevant, but I just need to know which is the faster construct. That and...

在网络上目前对他们提供的信息是混乱的。很多人说的foreach是不好的,但在技术上,因为它的假设,以简化编写使用迭代器遍历数组应该会更快。迭代器,这再次假设是快,但在PHP中也明显慢死(或这是不是一个PHP的事情吗?)。我说的是阵列功能:下一个()preV()复位()等好,如果他们甚至功能,而不是那些PHP语言的功能,看起来像一个功能

The information currently available on them on the net is confusing. A lot of people say foreach is bad, but technically it should be faster since it's suppose to simplify writing a array traversal using iterators. Iterators, which are again suppose to be faster, but in PHP are also apparently dead slow (or is this not a PHP thing?). I'm talking about the array functions: next() prev() reset() etc. well, if they are even functions and not one of those PHP language features that look like functions.

要缩小下来一点的:我不是在任何东西穿越步阵列超过1有趣的(没有负任何的步骤,也就是反向迭代)。我也没有兴趣遍历从任意点,仅仅0长度。我也看不出有超过1000项发生定期操作数组,但我确实看到一个阵列被遍历多次在应用程序的逻辑!另外,作为运营,在很大程度上只是字符串操作和echo'ing。

To narrow this down a little: I'm not interesting in traversing arrays in steps of anything more than 1 (no negative steps either, ie. reverse iteration). I'm also not interested in a traversal to and from arbitrary points, just 0 to length. I also don't see manipulating arrays with more than 1000 keys happening on a regular basis, but I do see a array being traversed multiple times in the logic of a application! Also as for operations, largely only string manipulation and echo'ing.

这里有一些参考的网站:结果
http://www.phpbench.com/ 结果
http://www.php.lt/benchmark/phpbench.php

Here are few reference sites:
http://www.phpbench.com/
http://www.php.lt/benchmark/phpbench.php

我听到到处都是什么:


  • 的foreach 是缓慢的,因此 / ,而更快

  • PHP的的foreach 将它遍历数组;使其更快,你需要使用引用

  • code这样的: $键= array_keys($ aHash); $大小=整型尺寸($键);
    为($ i = 0; $ I< $大小; $ I ++)
    比快的foreach

  • foreach is slow, and thus for/while is faster
  • PHPs foreach copies the array it iterates over; to make it faster you need to use references
  • code like this: $key = array_keys($aHash); $size = sizeOf($key);
    for ($i=0; $i < $size; $i++)
    is faster than a foreach

下面是我的问题。我写这个测试脚本: http://pastebin.com/1ZgK07US 并不管我多少次运行该脚本,我得到的东西像这样的:

Here's my problem. I wrote this test script: http://pastebin.com/1ZgK07US and no matter how many times I run the script, I get something like this:

foreach 1.1438131332397
foreach (using reference) 1.2919359207153
for 1.4262869358063
foreach (hash table) 1.5696921348572
for (hash table) 2.4778981208801

在短:


  • 的foreach 的foreach 更快参照

  • 的foreach 更快

  • 的foreach 更快为一个哈希表

  • foreach is faster than foreach with reference
  • foreach is faster than for
  • foreach is faster than for for a hash table

有人能解释一下吗?


  1. 难道我做错了什么?

  2. 是PHP的foreach参考事实拍什么区别?我的意思是为什么,如果你通过引用传递它不能复制呢?

  3. 什么是等价的迭代器code对foreach语句的;我见过,每次在网络上几个,但我对它们进行测试的时机路要走;我还测试了几个简单的迭代器的结构,但似乎从来没有连像样的成绩 - 在PHP中的数组迭代器很可怕

  4. 是否有更快的方式/方法/构造迭代虽然比/ FOREACH(和WHILE)以外的阵列?

PHP 5.3.0版本



修改:答案
与这里的人的帮助,我能够答案拼凑所有问题。我在这里总结一下它们:

PHP Version 5.3.0


Answer With help from people here I was able to piece together the answers to all question. I'll summarize them here:


  1. 难道我做错了什么?的共识似乎是:是的,我不能在基准测试使用的回声。就个人而言,我还没有看到如何回声一些函数的执行随机的时间或其它任何功能是如何以某种方式有什么不同 - 这和脚本只是产生的foreach同样的结果更好的能力比一切都硬虽则只是你使用的回声(以及我应该一直在使用)解释。不过,我承认这个测试应该用更好的东西来完成;虽然理想的妥协不会浮现在脑海中。

  2. 是PHP的foreach参考事实拍区别吗?我的意思是为什么,如果你通过引用传递它不能复制吗?的ircmaxell表明,的确是这样,进一步的测试似乎在大多数证明参考的情况下应该快了 - 尽管给我的code以上的片段,最绝对不意味着所有。我接受的问题可能是太不直观,在这样一个水平打扰,将需要一些极端的,如反编译实际确定这是每种情况更好。

  3. 什么是等价的迭代器code对foreach语句的,我已经看到了一些在网络上,但每次都让我测试它们的时机路要走,我还测试了几个简单的迭代器构造,但似乎从来没有连像样的成绩 - 在PHP中的数组迭代器很可怕的ircmaxell波纹管所提供的答案;虽然code可能只适用于PHP版本> = 5

  4. 是否有更快的方式/方法/构造迭代虽然比/ FOREACH(和WHILE)以外的阵列?的感谢去戈登的答案。使用PHP5中的新的数据类型应该给无论是性能提升或内存提升(根据您的情况其中任何一个可能是可取的)。虽然速度明智了很多新类型的数组的似乎并不比数组好()时,splpriorityqueue和splobjectstorage似乎要快得多。戈登提供的链接:<一个href=\"http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/\">http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/

  1. "Am I doing something wrong?" The consensus seems to be: yes, I can't use echo in benchmarks. Personally, I still don't see how echo is some function with random time of execution or how any other function is somehow any different -- that and the ability of that script to just generate the exact same results of foreach better than everything is hard to explain though just "you're using echo" (well what should I have been using). However, I concede the test should be done with something better; though a ideal compromise does not come to mind.
  2. "Is PHP foreach reference thing really making a difference? I mean why would it not copy it if you pass by reference?" ircmaxell shows that yes it is, further testing seems to prove in most cases reference should be faster -- though given my above snippet of code, most definitely doesn't mean all. I accept the issue is probably too non-intuitive to bother with at such a level and would require something extreme such as decompiling to actually determine which is better for each situation.
  3. "What's the equivalent iterator code for the foreach statement; I've seen a few on the net but each time I test them the timing is way off; I've also tested a few simple iterator constructs but never seem to get even decent results -- are the array iterators in PHP just awful?" ircmaxell provided the answer bellow; though the code might only be valid for PHP version >= 5
  4. "Are there faster ways/methods/constructs to iterate though a array other than FOR/FOREACH (and WHILE)?" Thanks go to Gordon for the answer. Using new data types in PHP5 should give either a performance boost or memory boost (either of which might be desirable depending on your situation). While speed wise a lot of the new types of array don't seem to be better than array(), the splpriorityqueue and splobjectstorage do seem to be substantially faster. Link provided by Gordon: http://matthewturland.com/2010/05/20/new-spl-features-in-php-5-3/

谢谢大家谁试图帮助。

我很可能坚持的foreach(非基准版本)的任何简单的穿越。

I'll likely stick to foreach (the non-reference version) for any simple traversal.

推荐答案

我的个人意见是用什么在上下文是有道理的。个人而言,我几乎从来不使用的数组遍历。我将其用于其他类型的迭代,但的foreach 是太容易...的时间差将是在大多数情况下最小的。

My personal opinion is to use what makes sense in the context. Personally I almost never use for for array traversal. I use it for other types of iteration, but foreach is just too easy... The time difference is going to be minimal in most cases.

大事情需要注意的是:

for ($i = 0; $i < count($array); $i++) {

这是一个昂贵的循环,因为它的每一次迭代调用次数。只要你不这样做,我不认为它真正的问题...

That's an expensive loop, since it calls count on every single iteration. So long as you're not doing that, I don't think it really matters...

作为发挥作用的参考,PHP使用写入时复制,所以如果你不写到阵列中,会有比较小的开销,而循环。但是,如果你开始修改阵列内的阵列,这就是你会开始看到它们之间的差异(因为人们需要将整个阵列的复制和参考只需修改在线)...

As for the reference making a difference, PHP uses copy-on-write, so if you don't write to the array, there will be relatively little overhead while looping. However, if you start modifying the array within the array, that's where you'll start seeing differences between them (since one will need to copy the entire array, and the reference can just modify inline)...

对于迭代器,的foreach 等价于:

$it->rewind();
while ($it->valid()) {
    $key = $it->key();     // If using the $key => $value syntax
    $value = $it->current();

    // Contents of loop in here

    $it->next();
}

至于有速度更快的方式来迭代,这真的取决于问题。但我真的要问,为什么?我理解想使事情变得更加高效,但我认为你是在浪费你的时间为一个微型优化。请记住, premature优化是根万恶 ...

编辑:基于的评论,我决定做一个快速的基准测试中...

Based upon the comment, I decided to do a quick benchmark run...

$a = array();
for ($i = 0; $i < 10000; $i++) {
    $a[] = $i;
}

$start = microtime(true);
foreach ($a as $k => $v) {
    $a[$k] = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {
    $v = $v + 1;
}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => $v) {}
echo "Completed in ", microtime(true) - $start, " Seconds\n";

$start = microtime(true);
foreach ($a as $k => &$v) {}    
echo "Completed in ", microtime(true) - $start, " Seconds\n";

和结果:

Completed in 0.0073502063751221 Seconds
Completed in 0.0019769668579102 Seconds
Completed in 0.0011849403381348 Seconds
Completed in 0.00111985206604 Seconds

所以,如果你修改了循环数组,它的速度更快几次使用引用...

So if you're modifying the array in the loop, it's several times faster to use references...

和只是参考的开销其实比复制阵列(这是5.3.2)少...所以它出现(在5.3.2至少),如果引用是显著快...

And the overhead for just the reference is actually less than copying the array (this is on 5.3.2)... So it appears (on 5.3.2 at least) as if references are significantly faster...

这篇关于出于性能VS在PHP FOREACH的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆