It’s an AppleScript quirk that getting or setting items in a list is greatly speeded up if the list variable is referenced rather than being used directly. The AppleScript Language Guide gives examples of this used when building a list, which I’ve paraphrased below. However, running these two particular scripts in AppleScript Editor on my Snow Leopard machine produces almost exactly the same timings (5 or 6 seconds). But I’m sure there was a vast difference on earlier systems:
set bigList to {}
set numItems to 100000
set t to (current date)
repeat with n from 1 to numItems
set end of bigList to n -- Using 'bigList' directly.
end repeat
set total to (current date) - t
set bigList to {}
set bigListRef to a reference to bigList --> bigList of «script»
set numItems to 100000
set t to (current date)
repeat with n from 1 to numItems
set end of bigListRef to n -- Referencing 'bigList' as a property of the current script.
end repeat
set total to (current date) - t
But once the list has been built, the old speed dichotomy still applies when accessing its items:
set bigList to {}
set numItems to 100000
repeat with n from 1 to numItems
set end of bigList to n
end repeat
set t to (current date)
repeat with n from 1 to numItems
get item n of bigList -- Direct use of 'bigList'.
end repeat
set total to (current date) - t --> About 592 seconds to get all the items in turn.
set bigList to {}
set bigListRef to a reference to bigList --> bigList of «script»
set numItems to 100000
repeat with n from 1 to numItems
set end of bigListRef to n
end repeat
set t to (current date)
repeat with n from 1 to numItems
get item n of bigListRef -- 'bigList' referenced.
end repeat
set total to (current date) - t --> About 1 second to get all the items in turn.
The value of bigListRef is bigList of «script» ” that is, the variable bigList belonging to the current script. So instead of using the bigListRef, you could write my bigList, which means exactly the same thing. Because it’s written directly into the source code rather than being stored in a variable, it’s actually very slightly faster still.
Only properties, globals, and run-handler variables can be referenced. Local variables can’t. The trick with them, say inside a normal handler, is to set up a temporary script object with a property, set that property to the list, then reference the property through the script object:
set bigList to {}
set bigListRef to a reference to bigList --> bigList of «script»
set numItems to 100000
repeat with n from 1 to numItems
set end of bigListRef to n
end repeat
timeGettingItems(bigList) --> About 0 seconds to get all the items in turn.
on timeGettingItems(bigList)
script o -- Temporary script object .
property l : bigList -- . with a property set to the passed list.
end script
set numItems to (count bigList)
set t to (current date)
repeat with n from 1 to numItems
get item n of o's l -- 'o's l' references the script object's property.
end repeat
return (current date) - t
end timeGettingItems
The run-handler variable bigList, the variable bigList inside the handler, and the script object’s property l are different variables, but they “contain” exactly the same physical list. Changes to the items of o’s l inside the handler will show up as changes in bigList outside it.
The referencing trick is only an advantage when accessing items (and properties, if I remember correctly) of a list. Actions involving the list itself are actually slightly faster without a reference. That’s why I wrote (count bigList) inside the handler rather than (count o’s l), although it doesn’t really make a lot of difference.