AppleScript performance tips

You can make your AppleScripts run much faster with one simple trick: use the get command frequently.

The fastest way to specify a media version is using its unique ID property. However, when writing a script you’ll probably specify media versions through some other relationship, such as media versions of box "Import". When you use a variable with that kind of specifier, AppleScript will evaluate it every time the variable is used to get the media version IDs. You can resolve a specifier into a list of IDs by using get.

Looping with a specifier

Consider the following script,

An inefficient script
tell application "Musebox"
tell current library
repeat with aMediaVersion in media versions of box "Import"
set the rating of aMediaVersion to 1
end repeat
end tell
end tell

When AppleScript evaluates aMediaVersion in the loop, it will send events as follows,

Events
set rating of item 1 of every media version of box "Import" of current library to 1
set rating of item 2 of every media version of box "Import" of current library to 1
...
set rating of item 45 of every media version of box "Import" of current library to 1

This means at every step through the loop, it asks Musebox to get every media version in a box — and to find that box by name — and use one item from it.

Resolving a specifier

However, if we add a get to the script as follows,

An improved script
tell application "Musebox"
tell current library
repeat with aMediaVersion in (get media versions of box "Import")
set the rating of aMediaVersion to 1
end repeat
end tell
end tell

AppleScript will resolve the specifier into a list of IDs instead of running a query for media versions every time,

Events
set rating of media version id "some-id" of box id "some-box-id" of current library to 1
set rating of media version id "some-other-id" of box id "some-box-id" of current library to 1
...

This is more efficient because it only searches for media versions once, at the beginning.

Referencing items by ID

The above script still asks Musebox to get the box every time. A media version’s ID is unique in the library, so it’s faster if the script just asks the current library for media versions directly,

A fast script that's tedious to write
tell application "Musebox"
tell current library
set theVersionIDs to (get id of every media version of box "Import")
repeat with i from 1 to the count of theVersionIDs
set theID to item i of theVersionIDs
set the rating of media version id theID to 1
end repeat
end tell
end tell

AppleScript will send the following events for each step through the repeat loop:

Events
set rating of media version id "some-id" of current library to 1
set rating of media version id "some-other-id" of current library to 1
...

Avoiding loops

This example is actually trivial enough to do with one event, without using a loop:

tell application "Musebox"
tell current library
set rating of every media version of box "Import" to 2
end tell
end tell