Bug #68392 [Opn->Nab]: foreach memory usage increase
Edit report at https://bugs.php.net/bug.php?id=68392&edit=1
ID: 68392
Updated by: rasmus@php.net
Reported by: ryan dot brothers at gmail dot com
Summary: foreach memory usage increase
-Status: Open
+Status: Not a bug
Type: Bug
Package: Performance problem
Operating System: Linux
PHP Version: 5.6.2
Block user comment: N
Private report: N
New Comment:
That's due to how it is implemented prior to PHP7. In PHP7 it is much smarter. You test code on
7:
2097152
2097152
2097152
2097152
Previous Comments:
------------------------------------------------------------------------
[2014-11-12 12:28:27] ryan dot brothers at gmail dot com
Yes, that's true, but if you use my original script and remove the foreach line in
test_function, then the memory usage remains the same too. I thought PHP uses copy-on-write rules
to avoid duplicating variables. Does doing a foreach on a variable count as writing to it?
Note also that the memory usage is higher if you do:
foreach ($rows as &$row)
rather than:
foreach ($rows as $row)
I'm not sure why doing &$row uses more memory vs doing $row.
------------------------------------------------------------------------
[2014-11-12 09:19:39] xczgamer at gmail dot com
PHP copies arrays when send to a function.
Hence yes, the memory almost doubles as the entire array gets copied.
If you change the following line:
function test_function($rows)
to:
function test_function(&$rows)
The memory usage will remain the same.
------------------------------------------------------------------------
[2014-11-10 17:39:29] ryan dot brothers at gmail dot com
Description:
------------
In the below example, the foreach in the global scope doesn't use any extra memory, but the
memory usage almost doubles from doing the foreach inside test_function. Is there a reason that so
much extra memory is used? I was expecting it not to use any extra memory as the foreach is done
using a reference for each array element.
Test script:
---------------
<?php
function test_function($rows)
{
echo memory_get_usage(true)."\n";
foreach ($rows as &$row)
{
}
unset($row);
echo memory_get_usage(true)."\n";
};
$rows = range(1, 10000);
echo memory_get_usage(true)."\n";
foreach ($rows as &$row)
{
}
unset($row);
echo memory_get_usage(true)."\n";
test_function($rows);
Expected result:
----------------
1835008
1835008
1835008
1835008
Actual result:
--------------
1835008
1835008
1835008
3407872
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68392&edit=1
Thread (4 messages)