php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72745 reset() work much slower than foreach()
Submitted: 2016-08-03 15:22 UTC Modified: 2016-08-06 14:04 UTC
From: sailormax at inbox dot lv Assigned:
Status: Wont fix Package: Arrays related
PHP Version: 7.0.9 OS:
Private report: No CVE-ID: None
Have you experienced this issue?
Rate the importance of this bug to you:

 [2016-08-03 15:22 UTC] sailormax at inbox dot lv
Description:
------------
reset() work much slower than foreach() under PHP7

Looks like developers optimized foreach(), but forgot about reset(). Under PHP5 speeds are similar.

Test script:
---------------
$arr = array_fill(0, 10000, "a");

$ts = microtime(true);
$first_key = -1;
foreach ($arr as $k => $v)
{
	$arr2 = $arr;
	reset($arr2);
	$first_key = key($arr2);
}
echo microtime(true)-$ts, "<br />\n";
echo $first_key, "<br />\n";

$ts = microtime(true);
$first_key = -1;
foreach ($arr as $k => $v)
{
	$arr2 = $arr;
	foreach ($arr2 as $k2 => $v2) break;
	$first_key = $k2;
}
echo microtime(true)-$ts, "<br />\n";
echo $first_key, "<br />\n";



Expected result:
----------------
0.0011060237884521
0
0.0011060237884521
0

Actual result:
--------------
0.64054489135742
0
0.0011060237884521
0

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-08-06 14:04 UTC] nikic@php.net
-Status: Open +Status: Wont fix
 [2016-08-06 14:04 UTC] nikic@php.net
I'm afraid there is not much we can do here. The problem you're running into is that reset($arr2) is forced to actually perform the copy that was delayed in the $arr2 = $arr line. This means you're copying the array on each iteration. The reason is that reset($arr2) actually modifies $arr2 (it modifies the internal array pointer), while as of PHP 7 by-value foreach no longer modifies $arr2 (it uses an external array pointer).

If possible, try to avoid using reset(), or alternatively don't copy the array beforehand. Doing reset($arr) (without $arr2 = $arr) should give you non-quadratic performance.
 
PHP Copyright © 2001-2021 The PHP Group
All rights reserved.
Last updated: Sun Jul 25 13:01:23 2021 UTC