Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:51324 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 7569 invoked from network); 19 Jan 2011 19:05:30 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jan 2011 19:05:30 -0000 Authentication-Results: pb1.pair.com smtp.mail=larry@garfieldtech.com; spf=permerror; sender-id=unknown Authentication-Results: pb1.pair.com header.from=larry@garfieldtech.com; sender-id=unknown Received-SPF: error (pb1.pair.com: domain garfieldtech.com from 76.96.27.243 cause and error) X-PHP-List-Original-Sender: larry@garfieldtech.com X-Host-Fingerprint: 76.96.27.243 qmta13.emeryville.ca.mail.comcast.net Received: from [76.96.27.243] ([76.96.27.243:48930] helo=qmta13.emeryville.ca.mail.comcast.net) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id 74/FC-41614-9F5373D4 for ; Wed, 19 Jan 2011 14:05:29 -0500 Received: from omta11.emeryville.ca.mail.comcast.net ([76.96.30.36]) by qmta13.emeryville.ca.mail.comcast.net with comcast id xX3E1f0070mlR8UADX5SHm; Wed, 19 Jan 2011 19:05:26 +0000 Received: from earth.ufp ([98.220.236.211]) by omta11.emeryville.ca.mail.comcast.net with comcast id xX5R1f00c4aLjBW8XX5RXy; Wed, 19 Jan 2011 19:05:26 +0000 Received: from localhost (localhost [127.0.0.1]) by earth.ufp (Postfix) with ESMTP id 33CCDD7A66 for ; Wed, 19 Jan 2011 13:05:25 -0600 (CST) Received: from earth.ufp ([127.0.0.1]) by localhost (earth.ufp [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id t15R+3A6Lz7U for ; Wed, 19 Jan 2011 13:05:25 -0600 (CST) Received: from garfield.ad.palantir.net (unknown [209.41.114.202]) by earth.ufp (Postfix) with ESMTPSA id CA224D7A59 for ; Wed, 19 Jan 2011 13:05:24 -0600 (CST) Message-ID: <4D3735F3.7020502@garfieldtech.com> Date: Wed, 19 Jan 2011 13:05:23 -0600 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-US; rv:1.9.2.13) Gecko/20101207 Lightning/1.0b2 Thunderbird/3.1.7 MIME-Version: 1.0 To: internals@lists.php.net References: <201101190045.31781.larry@garfieldtech.com> <4D368C58.2040903@yahoo.com.au> <201101190109.52250.larry@garfieldtech.com> <4D369473.4040608@yahoo.com.au> In-Reply-To: Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] How deep is copy on write? From: larry@garfieldtech.com ("larry@garfieldtech.com") So it sounds like the general answer is that if you pass a complex array to a function by value and mess with it, data is duplicated for every item you modify and its direct ancestors up to the root variable but not for the rest of the tree. For objects, because of their "pass by handle"-type behavior you are (usually) modifying the same data directly so there's no duplication. Does that sound correct? Related: What is the overhead of a ZVal? I'm assuming it's a fixed number of bytes. --Larry Garfield On 1/19/11 11:27 AM, Gustavo Lopes wrote: > On Wed, 19 Jan 2011 14:23:49 -0000, Martin Scotta > wrote: > >> What about objects? > > With objects less copying occurs because the object value (zval) data is > actually just a pointer and an id that for most purposes works as a > pointer. > > However, it should be said that while a copy of an array forces more > memory to be copied, the inner zvals are not actually copied. In this > snippet: > > $a = array(1, 2, array(3)); > $b = $a; > function separate(&$dummy) { } > separate($a); > > the copy that occurs when you force the separation of the zval that is > shared by $a and $b ($b = $a doesn't copy the array in $a to $b, it > merely copies the zval pointer of $a to $b and increments its reference > count) is just a shallow copy of hash table and a increment of the first > level zvals' refcounts. This means the zvals that have their pointers > stored in the array $a's HashTable are not themselves copied. > > Interestingly (or should I say, unfortunately), this happens even if the > inner zvals are references. See > http://php.net/manual/en/language.references.whatdo.php the part on arrays. > >> >> class Foo { >> public $foo; >> } >> >> function test($o) { >> $o->foo->foo->foo = 2; >> } >> >> $bar = new Foo; >> $bar->foo = new Foo; >> $bar->foo->foo = new Foo; >> >> test( $bar ); > > This example shows no copying (in the sense of "new zval allocation on > passing or assignment") at all. > >> >> --- >> Also... is it better to pass an object as a parameter rather than many >> values? >> >> function withValues($anInteger, $aBool, $aString) { >> var_dump($anInteger, $aBool, $aString); >> } >> >> function withObject(ParamOject $o) { >> var_dump( $o->theInteger(), $o->theBool(), $o->theString() ); >> } >> > > It should be indifferent. In normal circumstances, there is no zval > copying at all (only the pointers of arguments' symbols are copied). > Only when you start throwing references into the mix will you start > forcing copied. > >