php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73571 foreach() way slower than while(list($key,$value)=each($arr))
Submitted: 2016-11-21 08:56 UTC Modified: 2016-11-21 09:46 UTC
From: spam2 at rhsoft dot net Assigned:
Status: Not a bug Package: Performance problem
PHP Version: 7.0.13 OS:
Private report: No CVE-ID: None
 [2016-11-21 08:56 UTC] spam2 at rhsoft dot net
Description:
------------
since you depreacte each() with PHP 7.2 better fix foreach() before

[harry@srv-rhsoft:/downloads]$ php each.php
Extract:  0.031516075134277
While:    0.0004878044128418
For-Each: 0.11238217353821


Test script:
---------------
[harry@srv-rhsoft:/downloads]$ cat each.php
<?php
$loops = 2000;

for($x=1;$x<$loops;$x++)
{
 $arr['key' . $x] = 'Test';
}

echo "Extract:  ";
$start = microtime(true);
for($x=1;$x<$loops;$x++)
{
 extract($arr, EXTR_SKIP);
}
echo microtime(true) - $start . "\n";

echo "While:    ";
$start = microtime(true);
for($x=1;$x<$loops;$x++)
{
 while(list($key,$value)=each($arr))
 {
  ${$key} = $value;
 }
}
echo microtime(true) - $start . "\n";

echo "For-Each: ";
$start = microtime(true);
for($x=1;$x<$loops;$x++)
{
 foreach($arr as $key=>$value)
 {
  ${$key} = $value;
 }
}
echo microtime(true) - $start . "\n";
?>


Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-11-21 09:19 UTC] requinix@php.net
-Status: Open +Status: Not a bug
 [2016-11-21 09:19 UTC] requinix@php.net
I'll skip the sarcastic response I had planned and instead point out that you didn't reset($arr). Additionally, using EXTR_SKIP gives extract() an advantage over the other two as it doesn't have to re/create variables on loops $x>1. With those two fixed I get

Extract:  0.73130393028259
While:    10.98973608017
For-Each: 0.69374203681946

So it turns out that foreach is actually the fastest.
 [2016-11-21 09:36 UTC] spam2 at rhsoft dot net
forget the extract() stuff

reset($arr) is a bit unfair since it's a additional function call
 [2016-11-21 09:46 UTC] requinix@php.net
Additional, yes, but it is required if you use each() - at least if you do multiple times on the same array.

http://php.net/manual/en/function.each.php
> After each() has executed, the array cursor will be left on the next element of the
> array, or past the last element if it hits the end of the array. You have to use
> reset() if you want to traverse the array again using each.

https://3v4l.org/ncnBZ
(note the behavior changed with PHP 7: http://php.net/migration70.incompatible#migration70.incompatible.foreach.array-pointer)
 
PHP Copyright © 2001-2020 The PHP Group
All rights reserved.
Last updated: Tue Feb 25 22:01:25 2020 UTC