Section 22.3. List Access


22.3. List Access

When you access an attribute of a list, it is much faster to target a reference to the list, or the list as a script property, than to target the list directly. It's not entirely clear why this is; it seems like a bug. But it's a venerable and acknowledged bug, because even Apple's earliest documentation on AppleScript contains an example illustrating this point.

In this code (based on Apple's example) we total the numbers in a long list:

 set L to {} set total to 0 set bignum to 5000 repeat with i from 1 to bignum     set end of L to i end repeat repeat with i from 1 to bignum     set total to total + (item i of L) end repeat total -- 12502500, and it takes about 22 seconds to run on my machine

The big slowdown here is the second repeat block, accessing items of the list. If we access these items by way of a reference to the list, things speed up dramatically:

 set L to {} set refL to a reference to L set total to 0 set bignum to 5000 repeat with i from 1 to bignum     set end of L to i end repeat repeat with i from 1 to bignum     set total to total + (item i of refL) end repeat total -- 12502500, and it took less than a second

Instead of a reference, you can get the same extraordinary speed bump by referring to the list as a script property:

 set L to {} set total to 0 set bignum to 5000 repeat with i from 1 to bignum     set end of L to i end repeat repeat with i from 1 to bignum     set total to total + (item i of my L) end repeat total -- 12502500, and it took less than a second

The magic word in that code is my. Take it away, and the code takes 22 seconds to run; with it, the code runs in less than a second. (Discovery of this remarkable device is generally credited to Serge Belleudy-d'Espinose.)

Now suppose all of that code is part of a handler, where L is a local variable. You can't take a reference to L, so you'd have to use the trick of making L a script property. To do so, you might have to create a script object expressly for this purpose; that may seem silly, but it's worth it:

 on myHandler( )     set L to {}     script myScript         property refL : L     end script     set total to 0     set bignum to 5000     repeat with i from 1 to bignum         set end of L to i     end repeat     repeat with i from 1 to bignum         set total to total + (item i of myScript's refL)     end repeat     return total end myHandler myHandler( ) -- 12502500, and it took less than a second

I've been unable to arrive at a rule explaining what causes list access to be slow and when it isn't. In the examples in this section, the first repeat block (containing set end of) is fast; it's the second repeat block that's slow. But this does not mean that set end of is always fast. Sometimes it's slow too, and I don't know why. However, all you need to know is that, in such cases, the tricks with reference-based or property-based access will speed it up. So these should be among the first weapons in your arsenal when you're looking for ways to optimize your code.




AppleScript. The Definitive Guide
AppleScript: The Definitive Guide, 2nd Edition
ISBN: 0596102119
EAN: 2147483647
Year: 2006
Pages: 267
Authors: Matt Neuburg

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net