Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Memory usage and 'copy question.

From: joel:neely:fedex at: 26-Feb-2002 20:37

Hi, Alan, Not that simple... (What ever is? ;-) alan parman wrote:
> Case 1 > If I do new-value: copy value > then I get a clone of 'value and both 'new-value and 'value > take up the same amount of memory (disregarding the different > names), such that now there is twice the amount used than with > only 'value. >
You're describing COPY/DEEP and not simply COPY. See below.
> Case 2 > If I do new-value: value > then I get a "pointer" named 'new-value that will give me 'value. > I can change either 'value or 'new-value, and when called either > will give the changed contents. >
There are women and children present; let's say "reference" instead of the "p"-word... ;-)
> *** Please confirm: in this second case, the amount of new memory > used for 'new-value is only for creating the new name, and only > one copy of the contents of 'value exists. > > In other words (approximately): > (memory used in case 1) = 2 * (memory used in case 2) >
Using COPY without the /DEEP refinement only creates a copy of the "top level" of a series. For example, lets have some things...
>> thing1: "some string"
== "some string"
>> thing2: ["this" "is" "a" "series"]
== ["this" "is" "a" "series"]
>> thing3: [1 3 5 7]
== [1 3 5 7]
>> thing4: http://www.rebolforces.com/
== http://www.rebolforces.com/ ...and put 'em in a block...
>> thingblock: reduce [thing1 thing2 thing3 thing4]
== ["some string" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/] ...which we can copy...
>> otherthingblock: copy thingblock
== ["some string" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/] Now let's mess with that first thing...
>> append thing1 " goes here"
== "some string goes here" ...and check on our blocks...
>> thingblock
== ["some string goes here" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/]
>> otherthingblock
== ["some string goes here" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/] Now let's mess with THINGBLOCK itself...
>> append thingblock #"?"
== ["some string goes here" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/ #"?"]
>> otherthingblock
== ["some string goes here" ["this" "is" "a" "series"] [1 3 5 7] http://www.rebolforces.com/] This shows us that the COPY produced a distinct block, but the *references* to the series values within the block were copied, not those series values themselves. When we appended a new value to THINGBLOCK, OTHERTHINGBLOCK was not affected, but when we modified THING1, the two other references (in THINGBLOCK and OTHERTHINGBLOCK) could "see" the change. Therefore, the amount of memory consumed by making the copy was only the amount required for a reference, regardless of the size of the series value referred to by that reference. IOW, saying foo: [[[[[[[[[[0 1 2 3 4 5 6 7]]]]]]]]]] baz: copy foo adds much less overhead than foo: [0 1 2 3 4 5 6 7] baz: copy foo OTOH, if we do COPY/DEEP, then we are expecting a complete duplicate of all content at all levels -- a potentially dangerous thing to ask for! The following transcript (manually retyped!)
>> a: [0]
== [0]
>> b: [1]
== [1]
>> c: [2]
== [2]
>> append/only b c
== [1 [2]]
>> append/only a b
== [0 [1 [2]]]
>> append/only c a
== [2 [0 [1 [...]]]]
>> a
== [0 [1 [2 [...]]]]
>> d: copy/deep a
was followed by a complete crash of the REBOL interpreter. -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;