Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you efficiently build a list within a handler in AppleScript?

AppleScript documentation suggests the following code to efficiently build a list:

set bigList to {}
set bigListRef to a reference to bigList
set numItems to 100000
set t to (time of (current date)) --Start timing operations
repeat with n from 1 to numItems
    copy n to the end of bigListRef
end
set total to (time of (current date)) - t --End timing

Note the use of an explicit reference. This works fine at the top level of a script or within an explicit run handler, but if you run the same exact code verbatim within another handler like so:

on buildList()
    set bigList to {}
    set bigListRef to a reference to bigList
    set numItems to 100000
    set t to (time of (current date)) --Start timing operations
    repeat with n from 1 to numItems
        copy n to the end of bigListRef
    end
    set total to (time of (current date)) - t --End timing
end buildList
buildList()

it breaks, yielding an error message saying, "Can't make bigList into type reference." Why does this break, and what is the correct way to efficiently build a list within a handler other than run()?

like image 429
jricardo Avatar asked Oct 22 '22 13:10

jricardo


1 Answers

set end of l to i seems to be faster than copy i to end of l:

on f()
    set l to {}
    repeat with i from 1 to 100000
        set end of l to i
    end repeat
    l
end f
set t to time of (current date)
set l to f()
(time of (current date)) - t

You could also use a script object:

on f()
    script s
        property l : {}
    end script
    repeat with i from 1 to 100000
        copy i to end of l of s
    end repeat
    l of s
end f
set t to time of (current date)
set l to f()
(time of (current date)) - t

100000 is also over the limit of items that can be saved in compiled scripts, so you'll get an error like this if you run the script and try to save it as scpt:

The document “Untitled” could not be saved as “Untitled.scpt”.

You can either put set l to f() inside a handler so l is local, add set l to {} to the end, or save the script as .applescript.

like image 123
Lri Avatar answered Oct 31 '22 21:10

Lri