Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:51316 Return-Path: Mailing-List: contact internals-help@lists.php.net; run by ezmlm Delivered-To: mailing list internals@lists.php.net Received: (qmail 79981 invoked from network); 19 Jan 2011 07:36:26 -0000 Received: from unknown (HELO lists.php.net) (127.0.0.1) by localhost with SMTP; 19 Jan 2011 07:36:26 -0000 Authentication-Results: pb1.pair.com header.from=mail_ben_schmidt@yahoo.com.au; sender-id=unknown; domainkeys=good Authentication-Results: pb1.pair.com smtp.mail=mail_ben_schmidt@yahoo.com.au; spf=permerror; sender-id=unknown Received-SPF: error (pb1.pair.com: domain yahoo.com.au from 98.138.90.90 cause and error) DomainKey-Status: good X-DomainKeys: Ecelerity dk_validate implementing draft-delany-domainkeys-base-01 X-PHP-List-Original-Sender: mail_ben_schmidt@yahoo.com.au X-Host-Fingerprint: 98.138.90.90 nm27.bullet.mail.ne1.yahoo.com Received: from [98.138.90.90] ([98.138.90.90:22529] helo=nm27.bullet.mail.ne1.yahoo.com) by pb1.pair.com (ecelerity 2.1.1.9-wez r(12769M)) with ESMTP id B4/3A-18515-974963D4 for ; Wed, 19 Jan 2011 02:36:26 -0500 Received: from [98.138.90.54] by nm27.bullet.mail.ne1.yahoo.com with NNFMP; 19 Jan 2011 07:36:23 -0000 Received: from [98.138.89.161] by tm7.bullet.mail.ne1.yahoo.com with NNFMP; 19 Jan 2011 07:36:22 -0000 Received: from [127.0.0.1] by omp1017.mail.ne1.yahoo.com with NNFMP; 19 Jan 2011 07:36:22 -0000 X-Yahoo-Newman-Id: 924059.74083.bm@omp1017.mail.ne1.yahoo.com Received: (qmail 5548 invoked from network); 19 Jan 2011 07:36:22 -0000 DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; s=s1024; d=yahoo.com.au; h=DKIM-Signature:Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding; b=IM6lwVKQODV6QPPsAcSHPHXwPWeZOLqhKAF86Qp73DIdLZl8tEUMt00YQSv+fSOfM5LWZ6TAmvQvITZbgt9/i4ikF7DCFQ+qn3wbz3SZ4dgiH5MiLGya9iVKD1qM1V3jadkAb6SReDPbDkzQV1tbtqB85ihTE3+Vp+ugPpKlLEc= ; DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=yahoo.com.au; s=s1024; t=1295422582; bh=aIqp6pPhy+E6VXDsLhgayB3zQPQh+udX+K8klX8iAtI=; h=Received:X-Yahoo-SMTP:X-YMail-OSG:X-Yahoo-Newman-Property:Message-ID:Date:From:User-Agent:MIME-Version:To:CC:Subject:References:In-Reply-To:Content-Type:Content-Transfer-Encoding; b=Edh4xkKUucs/mH/YiT7H1LOPUHEVBidiLvHZm22RRIsaKthN0gdPXi5+gmoo/SeQVsI/2koxxsQZYIhV1HWFpQ8x43p0uv3bXzzVN4FW0SVQsksGJ7qfbIarQZmQeoMz34BhWQgrigrEddIMbV7c4YOlGPaVrCnLb0Yk93o4S5s= Received: from thought.local (mail_ben_schmidt@124.148.147.119 with plain) by smtp129.mail.mud.yahoo.com with SMTP; 18 Jan 2011 23:36:21 -0800 PST X-Yahoo-SMTP: enFMnPSswBAexaHyzgobwuUTrYOhZdJ0KRA2SjA- X-YMail-OSG: 76X_t94VM1lsazgjJBfiKjXNk1QzjXp.vz_1zdBmRmQtp8r 3rBy4LQJwKZvlXt_hllCus0uaHgyIbazDHHM2zBKXGK9_DycTroL.dexbWPd oqyg_2oK8tvn5OypJoKuP16Uaw5HMWjrLnhwXCO.X15gaU6X2Umr5bSB5zzs C.4SFbPTm3.4.I1e0j94h_1rlPDbHxscZR_Yu7DcrVpnh_1qF07IlbOrrcIM 6DsI631nomYOPyt6JZ.DLHLWzYDrEukkB9FOVnzVh8E8rYYuTBoxiIVd5RwA oo71hrTPoWZ0h5DDdXfuzBh.wvjlWKEfSrnoP622AKUtSm5I1gmzxOrgpzVg B8zml_vH7_EyxAHThsgNOWWmU X-Yahoo-Newman-Property: ymail-3 Message-ID: <4D369473.4040608@yahoo.com.au> Date: Wed, 19 Jan 2011 18:36:19 +1100 User-Agent: Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.6; en-GB; rv:1.9.2.13) Gecko/20101207 Thunderbird/3.1.7 ThunderBrowse/3.3.4 MIME-Version: 1.0 To: Larry Garfield CC: internals@lists.php.net References: <201101190045.31781.larry@garfieldtech.com> <4D368C58.2040903@yahoo.com.au> <201101190109.52250.larry@garfieldtech.com> In-Reply-To: <201101190109.52250.larry@garfieldtech.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Subject: Re: [PHP-DEV] How deep is copy on write? From: mail_ben_schmidt@yahoo.com.au (Ben Schmidt) 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 >