But only 1000 iterations over an array with only 3 members. Could be an anomaly, unless you ran each test 10 times and got the same result each time. Go 10000 times and make the string longer - like 50 digits. Then the results should be more definitive.
I did each test about a dozen times; what I posted was the average. There were some outliers. But, all in all, I didn't mean for it to be "definitive" anyway.
But, ask and ye shall receive: averages for 10,000 iterations, using PHP_INT_MAX (which, on my system (64 bit) was 9,223,372,036,854,775,807):
0.18127489089966 secJohn's first method:
0.20594382286072 secJohn's second method:
I think foreach is faster than while in this case because while has to do a full array lookup each iteration. Using foreach is perhaps somehow more sequential and/or the array is in memory.
In my imagination, foreach is a much more natural operation than for/while, but I haven't seen any evidence (until now) to support that. I don't know what kind of logic/math is actually behind it (I had always pessimistically assumed it was just a for loop using count(), roughly), but at least in theory I can imagine a very efficient mechanism that uses the array pointer to make it go faster-- in fact, I think that's exactly what's happening here. The array pointer is increased by one each time. Then by default it'll stop at the end of the array.
I don't know much about this, but I do know that arrays have points and that, if you do things the wrong way, they can actually mess things up-- like starting in the middle of the array next time, but only if you have very weird (and relatively low level / manual code, functions like reset() and friends).
I guess we're all just going to have to learn c++ and go find out.
I think Daniel and I are onto something. It seems fairly likely that since foreach means that the entire array is to be processed, the array is held in memory and the pointer is advanced incrementally for each iteration. Whereas, while and for loops are arbitrary. Each iteration could potentially involve anything. Just because the first iteration performs a lookup in an array, doesn't necessarily mean that same array will even be involved in the second iteration. So nothing is held in memory.