AppleScript_ The Definitive Guide - Matt Neuburg [203]
Only repetition really matters
Considerations of speed are probably not worth raising at all unless your script performs some sort of repetition, meaning either a handler calling itself recursively or a repeat block—and even then, not until the number of repetitions becomes significant. It is here, in a repetition, that a small difference in speed one way or the other can accumulate, as the same code is performed again and again, so as to have a big impact on how long your script takes to run.
Tools of the Trade
In order to improve speed, you have to measure it. At the crudest level, you can do this with the current date command, which captures the date-time at the moment it is issued, but this is good only to the nearest second. A better choice is the command the ticks from the Jon's Commands osax; this is particularly good for timing things, since a tick is about one-sixtieth of a second. Examples will appear later in this chapter.
Script Debugger can also help you quantify speed. It doesn't yet provide true code profiling (reporting the time spent on different sections of your code), but it does report how long the script took to run and how much of that time was spent within AppleScript and how much was spent sending Apple events and how many Apple events were sent. It also provides code coverage, indicating what lines of your code were actually executed, so you don't waste effort optimizing areas of your script that aren't doing anything.
Apple Events
Apple events are expensive, and some Apple events are very expensive. You can't do anything about the time spent waiting for each Apple event to execute, but perhaps you can minimize the number of Apple events sent. At the same time, you may be able to improve the efficiency of the particular Apple events you do send.
The boolean expression at the top of a repeat while block must be evaluated before every repetition of the block, and then once more in order to decide not to repeat the block any further. This means that it should not contain any commands whose result will not change during the repetition, as it would be needless and wasteful overhead to issue those commands each time through the loop.
Here's a silly but telling example. Suppose we have two folders in the Finder, and we want to create enough new folders inside the first folder so that it contains the same number of items as the second folder. The following code expresses neatly and elegantly what we want done:
set x to 1
tell application "Finder"
set f1 to folder "f1"
set f2 to folder "f2"
repeat while ((count items of f1) < (count items of f2))
make new folder at f1 with properties {name:("f" & x)}
set x to x + 1
end repeat
end tell
But in the world of AppleScript, neat and elegant isn't always good. That code sends the count message to the Finder twice for each time through the loop, when in fact we need only send it twice at the outset as we prepare for the loop:
set x to 1
tell application "Finder"
set f1 to folder "f1"
set f2 to folder "f2"
set c1 to count items of f1
set c2 to count items of f2
repeat while c1 < c2
make new folder at f1 with properties {name:("f" & x)}
set x to x + 1
set c1 to c1 + 1
end repeat
end tell
Observe that the same issue would not arise if I had coded this using repeat with x from...to, because that construct evaluates everything once at the outset and then never again.
Special considerations arise when using repeat with...in (see Chapter 19). The Apple events you send may be needlessly numerous and needlessly