Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

stefa.rossi

macrumors newbie
Original poster
Jul 15, 2014
2
0
Hello,

I need to optimize the following AppleScript:
Code:
set out to {}
tell application "iTunes"
	set a to tracks of playlist "Mobile"
	repeat with t in a
		set l to location of t
		set p to the POSIX path of l
		set s to the start of t
		set f to the finish of t
		copy {{location:POSIX path of l, start:start of t, finish:finish of t}} to the end of out
	end repeat
end tell
return out

As you can see, it returns the location, start time and finish time of each track of a playlist.
It takes ~ 14 seconds to run on my computer. Please let me know if you have any ideas. Thanks! :)
 
This should run about 3-4 times faster :

Code:
set locationStartAndFinishTimes to {}
set locationStartAndFinishTimesRef to a reference to locationStartAndFinishTimes
tell application "iTunes"
	set thePlaylist to playlist "Mobile"
	set countOfTracks to count of tracks of thePlaylist
	repeat with i from 1 to countOfTracks
		set theTrack to (a reference to track i of thePlaylist)
		copy {{location:(POSIX path of (get location of theTrack)), start:start of theTrack, finish:finish of theTrack}} to the end of locationStartAndFinishTimesRef
	end repeat
end tell
return contents of locationStartAndFinishTimesRef

The largest part (by far) of that speedup comes from the first two lines of that code, due to a quirk in the AppleScript runtime:
Apple said:
For large lists, it is more efficient to use the a reference to operator when inserting a large number of items into a list, rather than to access the list directly.

Hope that helps!

You also might enjoy this newly published free app by Shane Stanley , which times how long your script takes to run, in case you plan on experimenting further with this...
 
That's amazing, on my computer it takes just 2 seconds to run. Thank you very much!
 
This should run about 3-4 times faster :
[...]
The largest part (by far) of that speedup comes from the first two lines of that code, due to a quirk in the AppleScript runtime:

Specifically, AppleScript lists have terrible performance characteristics: the time it takes to look up a list item is proportional to the length of the list, instead of constant time as it should be[1]. So it's more accurate to say it will run more efficiently rather than X times faster, since 'X' varies according to list length: the bigger the list, the bigger the time saving the more efficient implementation provides.

The other way you can improve efficiency is by reducing the number of commands you send to the target application. Object specifiers are actually simple relational queries, not object-oriented references (which can only identify one item at a time), so when talking to a well-implemented application it's often possible to request a whole bunch of values all in one go.

Thus:

Code:
tell application "iTunes"
    tell every track of playlist "Mobile"
        set theLocations to its location
        set theStarts to its start
        set theFinishes to its finish
    end tell
end tell
{theLocations, theStarts, theFinishes}

That will give you three separate lists which you can then process using a 'repeat with i from 1 to count...' loop. Combined with the ugly but effective hack to make list item lookups constant-time, you should get pretty good performance out of it, even on large playlists.

(The AppleScript book I co-authored a few years back has a section covering common performance optimizations, not to mention lots of other handy info about AppleScript and application scripting in general. Link in sig.)

--

[1] i.e. O(n) instead of O(1), for those familiar with big-O notation. AppleScript lists are O(1) vector arrays, as in most languages, but there's some badly coded safety checking that causes the entire list to be iterated every time you get or set an item, which degrades efficiency to O(n), or linear time.
 
it's more accurate to say it will run more efficiently rather than X times faster, since 'X' varies according to list length
You’re absolutely right. :eek: And thanks for elaborating on that!

I always enjoy coming across your AppleScript related posts! This one’s no exception.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.