Re: COPY TO a list vs. SET TO a list
Re: COPY TO a list vs. SET TO a list
- Subject: Re: COPY TO a list vs. SET TO a list
- From: Christopher Nebel <email@hidden>
- Date: Wed, 19 Dec 2001 12:36:29 -0800
On Tuesday, December 18, 2001, at 12:31 AM, Olivier Berquin wrote:
Here is a script:
--
set theList to {,
{"Olivier", 2, 3, 5, 108}, ,
{"Martin", 17, 19, 20, 21}, ,
{"Frank", 4, 8, 48}}
set item 2 of theList to item 2 of theList & 6
copy 57 to end of item 3 of theList
--
What's the better way and why ?
There are two issues here: set vs. copy, and concatenation vs.
appending. For performance, set is preferable to copy, and appending is
preferable to concatenation, but they all have their virtues and
drawbacks.
SET vs. COPY: set does what's called a "sharing assignment", while copy
always clones the whole value. This makes a difference when using any
complex structure (i.e. lists, records, or strings). For instance:
set a to {1, 2, 3}
set b to a
set end of a to 4
b --> {1, 2, 3, 4}
"set a to b" makes a and b point to the same list storage, so changes to
a's storage affect b as well. Using "copy" would have made a complete
copy of a and put that into b, so a and b would have been independent.
This uses more memory, but sometimes it's what you want. This is
covered in the AppleScript Language Guide under Data Sharing, p. 206.
CONCAT vs. APPEND: if you want to add an item to a list, there are two
ways to do it. You can concatenate the old value with the new item like
this:
set a to a & new_item
...or you can append the item to the list directly, like this:
set end of a to new_item
The difference is a little subtle. In concatenation, what you're
actually doing is creating an entirely new list from the original
contents of a and the new item, and then assigning that new list back to
a. This means you have to copy the contents of a, which takes time and
memory.
In appending, you're modifying the contents of the list itself, so
there's no additional copy, thus saving time and memory. [1]
If you're always putting the new item at the end, appending is a clear
win. The problem with appending is that it only appends -- there's no
equivalent trick to create a new item in the middle of a list. In that
case, concatenation is your only option. The other thing is that
appending also affects shared variables, which is not always what you
want.
--Chris Nebel
AppleScript Engineering
[1] Astute readers will realize that AppleScript has to copy the list
at least sometimes, because there might not be room for the new
element. AppleScript currently grows lists by 16 slots at a time, so
you only need to copy the list once for every 16 appends, instead of
every time with concatenation. (Yes, I know that a different
algorithm -- e.g. doubling the slots -- would be more time-efficient.
I'm working on it.)