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...
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.
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.
Here are few reference sites:
What I hear everywhere:
foreachis slow, and thus
foreachcopies the array it iterates over; to make it faster you need to use references
- code like this:
$key = array_keys($aHash); $size = sizeOf($key);is faster than a
for ($i=0; $i < $size; $i++)
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
foreachis faster than
foreachis faster than
foreachis faster than
forfor a hash table
Can someone explain?
- Am I doing something wrong?
- Is PHP foreach reference thing really making a difference? I mean why would it not copy it if you pass by reference?
- 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?
- Are there faster ways/methods/constructs to iterate though a array other than FOR/FOREACH (and WHILE)?
PHP Version 5.3.0
Edit: Answer With help from people here I was able to piece together the answers to all question. I'll summarize them here:
- "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.
- "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.
- "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
- "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/
Thank you everyone who tried to help.
I'll likely stick to foreach (the non-reference version) for any simple traversal.