[TYPO3-dev] FYI: comparing execution speed of some php functions
Jigal van Hemert
jigal at xs4all.nl
Sat Jun 27 10:55:00 CEST 2009
Hi Myself ;-)
Jigal van Hemert wrote:
>> foreach() loop:
>> ---------------------------------------------
>> foreach() took 11.16920 ms
>> foreach() with KEY took 12.35318 ms
>>
>> while(list()=each()) loop:
>> ---------------------------------------------
>> while(list()...) took 58.12597 ms
>> while(list()...) with key took 64.06283 ms
>
> There is another difference between these two, see:
> http://www.php.net/manual/en/control-structures.foreach.php
>
> Quote: "Note: Unless the array is referenced, foreach operates on a copy
> of the specified array and not the array itself. foreach has some side
> effects on the array pointer. Don't rely on the array pointer during or
> after the foreach without resetting it. "
http://www.tuxradar.com/practicalphp/18/1/9 tells a different story:
Quote: "Furthermore, PHP makes extensive use of "copy-on-write", which
means taking ten copies of the same array is also free, because they all
point to the same object. It's called "copy-on-write" because the minute
one of the arrays change from the others, a full copy is made so the
change is kept separate."
Testing this gives very strange results:
Foreach loop
===================================
$a = 0;
$myarr2 = $myarr;
$first = true;
foreach ($myarr2 as $k => $v) {
$v = 4 * 45;
if ($first == true) {
echo 'memory usage inside loop: ', memory_get_usage(), "\n";
$first = false;
}
}
while(list()) loop:
===================================
$a = 0;
$myarr2 = $myarr;
$first = true;
reset($myarr2);
while (list($t) = each($myarr2)) {
$a = 4 * 45;
if ($first == true) {
echo 'memory usage inside loop: ', memory_get_usage(), "\n";
$first = false;
}
}
Foreach with reference to value (unmodified)
====================================
$a = 0;
$myarr2 = $myarr;
$first = true;
foreach ($myarr2 as $k => &$v) {
$a = 4 * 45;
if ($first == true) {
echo 'memory usage inside loop: ', memory_get_usage(), "\n";
$first = false;
}
}
Foreach with reference to value (modified)
====================================
$a = 0;
$myarr2 = $myarr;
$first = true;
foreach ($myarr2 as $k => &$v) {
$v = 4 * 45;
if ($first == true) {
echo 'memory usage inside loop: ', memory_get_usage(), "\n";
$first = false;
}
}
The numbers:
memory usage: 79264
fill an array with 100000 items:
---------------------------------------------
setting up array took 69.16404 ms
memory usage: 7404532
[So the array takes up about 6.5MB]
foreach() loop:
---------------------------------------------
memory usage before: 7404532
memory usage inside loop: 12329060
foreach() with KEY took 63.61604 ms
memory usage: 7468584
[According to tuxradar making a copy of an array should take up a
substantial amount of memory, but inside the foreach loop PHP uses quite
a bit more. The extra stuff is removed automatically when the loop ends.]
while(list()) loop:
---------------------------------------------
memory usage before: 7472512
memory usage inside loop: 12333504
while(list()) took 159.44004 ms
memory usage: 12333560
[This was expected to be slow, but unexpectedly the loop also took a
huge amount of memory. Even stranger, this memory hasn't been freed
after the loop ended!]
foreach() with reference to value, no change to array loop:
---------------------------------------------
memory usage before: 7468532
memory usage inside loop: 12329092
foreach() with KEY + reference to value took 61.81502 ms
memory usage: 14729132
[According to the manul a reference wouldn't require a copy of the array
for foreach. Inside the loop a lot of memory has been taken. Even though
the array hasn't been changed there is a copy present after the foreach
ends. The copy-on-write feature has been triggered by the reference!?!?]
foreach() with reference to value, changing array loop:
---------------------------------------------
memory usage before: 7468512
memory usage inside loop: 12351652
foreach() with KEY + reference to value took 56.69117 ms
memory usage: 14729160
[Not very much different than not changing the array, although the loop
is slightly faster than the loop that doesn't change the variable.
Apparently changing a simple variable outside the loop takes more time
than changing the array. There is a copy left when the foreach ends like
we expected.]
My conclusion:
Contrary to what we were taught in the era of PHP4 the foreach() loop
doesn't take up more memory than the while() loop. Foreach is way faster
than while and if you need to change the elements of the array use
foreach with references to the value(s).
Loops take up a lot of memory any way you do them.
A copy of the code is for some time available at
http://www.xs4all.nl/~dcbjht/typo3/looptest.txt
Regards,
--
Jigal van Hemert.
More information about the TYPO3-dev
mailing list