Applescript - 迭代库中所有 iTunes 曲目时性能不佳

Applescript - Poor performance iterating all iTunes tracks in the library

我正在尝试检查哪些曲目位于我的 iTunes 库目录中,哪些曲目未使用 AppleScript。

下面的脚本确实每首曲目大约需要 2 秒(曲库中大约有 8000 首曲目):

#!/usr/bin/osascript
tell application "iTunes"

        repeat with l in (location of every file track)
                set fileName to (POSIX path of l)
                if fileName does not start with "/Users/user/Music/iTunes/iTunes Media/" then
                        log fileName
                end if
        end repeat

end tell

也尝试了以下方法,但性能相同:

#!/usr/bin/osascript
tell application "iTunes"

        repeat with l in (location of every file track)
                POSIX path of l does not start with "/Users/user/Music/iTunes/iTunes Media/"
        end repeat

end tell

与此同时,iTunes 变得非常迟钝。

一定是在做一些愚蠢的事情,但不知道是什么。

这是在 2015 27' iMac 上的 OS X El Capitan 下。

感谢任何帮助。

干杯

您可以使用关键字 get

显着加快脚本速度
repeat with l in (get location of every file track)

区别是:

  • 没有get 每次迭代都会检索列表
  • get 列表被检索一次

两个问题:

  1. 发送大量 Apple 事件的费用很高。 repeat with l in (location of every file track) 为每个轨道发送一个单独的 get 事件(get location of file track 1get location of file track 2、...)。首先获取所有位置的列表,然后对其进行迭代。

  2. 由于糟糕的实现,获取 AppleScript 列表项所需的时间随着列表的长度线性增加;因此,迭代大型列表时的性能会下降(O(n*n) 而不是 O(n) 效率)。您可以使用令人讨厌的技巧将其降低到 O(n),通过引用引用列表项(例如,将列表粘贴到脚本对象 属性 中,然后引用它)。

示例:

set iTunesFolder to POSIX path of (path to music folder) & "iTunes/iTunes Media/"

tell application "iTunes"
    script
        property fileLocations : location of every file track
    end script
end tell
repeat with l in fileLocations of result
    set fileName to (POSIX path of l)
    if fileName does not start with iTunesFolder then log fileName
end repeat