Yep. PHP does clock up memory very quickly for big arrays, objects with lots of
members and/or lots of small objects with large overheads. There are a LOT of
zvals and zobjects and things around the place, and their overhead isn't all that
small.
Of course, if you go to the trouble to construct arrays using references, you can
avoid some of that, because a copy-on-write will just copy the reference. It does
mean you're passing references, though.
$bar['baz'] = 1;
$poink['narf'] = 1;
$a['foo']['bar'] =& $bar;
$a['foo']['poink'] =& $poink;
Then if you test($a), $bar and $poink will be changed, since they are 'passed by
reference'--no copying needs to be done. It's almost as if $b were passed by
reference, but setting $b['blip'] wouldn't show up in $a, because $a itself would
be copied in that case, including the references, which would continue to refer to
$bar and $poink. So a much quicker copy, but obviously not the same level of
isolation that you might expect or desire. Unless you did some jiggerypokery like
$b_bar=$b['bar']; $b['bar']=$b_bar; which would break the reference and make a
copy of just that part of the array. But this is a pretty nasty caller-callee
co-operative kind of thing. Just a thought to throw into the mix, though.
Disclaimer: I'm somewhat out of my depth here. But I'm sure someone will jump on
me if I'm wrong.
Ben.
On 19/01/11 6:09 PM, Larry Garfield wrote:
That's what I was afraid of. So it does copy the entire array. Crap. :-)
Am I correct that each level in the array represents its own ZVal, with the
additional memory overhead a ZVal has (however many bytes that is)?
That is, the array below would have $a, foo, bar, baz, bob, narf, poink,
poink/narf = 8 ZVals? (That seems logical to me because each its its own
variable that just happens to be an array, but I want to be sure.)
--Larry Garfield
On Wednesday, January 19, 2011 1:01:44 am Ben Schmidt wrote:
It does the whole of $b. It has to, because when you change 'baz', a
reference in 'bar' needs to change to point to the newly copied 'baz', so
'bar' is written...and likewise 'foo' is written.
Ben.
On 19/01/11 5:45 PM, Larry Garfield wrote:
Hi folks. I have a question about the PHP runtime that I hope is
appropriate for this list. (If not, please thwap me gently; I bruise
easily.)
I know PHP does copy-on-write. However, how "deeply" does it copy when
dealing with nested arrays?
This is probably easiest to explain with an example...
$a['foo']['bar']['baz'] = 1;
$a['foo']['bar']['bob'] = 1;
$a['foo']['bar']['narf'] = 1;
$a['foo']['poink']['narf'] = 1;
function test($b) {
// Assume each of the following lines in isolation...
// Does this copy just the one variable baz, or the full array?
$b['foo']['bar']['baz'] = 2;
// Does this copy $b, or just $b['foo']['poink']?
$b['foo']['poink']['stuff'] = 3;
return $b;
}
// I know this is wasteful; I'm trying to figure out just how wasteful.
$a = test($a);
test() in this case should take $b by reference, but I'm trying to
determine how much of a difference it is. (In practice my use case has
a vastly larger array, so any inefficiencies are multiplied.)
--Larry Garfield
--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php