2014-01-18 80 views
0

我有一些用於在OSX上構建iTunes庫的表示的applescript代碼,麻煩在於大型庫太大。如果用(目標)C語言編寫,我期望它快得多,但我不知道如何做到這一點。我知道它是一個bug問題,但是任何人都願意將它改寫爲(Objective)C。如何將此AppleScript代碼轉換爲iTunes以(Objective)C以提高性能

set thePath to (POSIX file "/tmp/songkong_itunes_model.txt") 
set fileref to open for access (thePath) with write permission 
tell application "iTunes" 
    set eof fileref to 0 
    set mainLibrary to library playlist 1 
    repeat with nexttrack in (get every track of mainLibrary) 
     if (class of nexttrack is file track) then 
      try 
       set trackname to name of nexttrack 
       set loc to location of nexttrack 
       set locpath to POSIX path of loc 
       set persistid to persistent ID of nexttrack 
       set nextline to trackname & "::" & locpath & "::" & persistid 
       tell current application to write nextline & "\n" as «class utf8» to fileref 
      end try 
     end if 
    end repeat 
end tell 
close access fileref 
return "" 

回答

2

「我預計,如果寫在(目標)C它是顯著更快」

不,它的速度慢主要是因爲你在可能的最沒有效率的方式獲取數據,一個值在時間。相同的算法在任何語言中都會很慢,因爲每個單獨的get都涉及到構建Apple事件並將其發送到iTunes進程,該進程必須解釋事件,查找所引用的值並將其發送回您的進程第二個回覆事件。

第二個問題是AppleScript在迭代大型列表時出了名 - 由於一些僞劣的實現,查找列表項所需的時間與列表長度直接相關,因此迭代所花費的時間整個列表以二次方式增加(即Big-O表示法中的效率爲O(n*n))。然而,解決這個問題有一個標準的問題,所以它不應該成爲一個交易斷路器。

您有幾種選擇:

  1. 如果靶向10.9+,你可以使用新的iTunesLibrary.framework檢索數據。

  2. 如果您需要支持10.8或更早的版本,你可以解析iTunes Music Library.xml文件在用戶的iTunes音樂文件夾中。

  3. 重寫您的AS代碼以減少發送的Apple事件的數量並優化迭代過程。

1和2你可以搞清楚你自己。 3,這裏是你如何檢索使用僅3 get事件的所有數據(!):

tell application "iTunes" 
    tell every file track of library playlist 1 
     set tracknames to its name 
     set locs to its location 
     set persistids to its persistent ID 
    end tell 
end tell 

這會給你3名不同的列表,你可以在平行遍歷:

set thePath to (POSIX file "/Users/has/songkong_itunes_model3.txt") 
set fileref to open for access (thePath) with write permission 
set eof fileref to 0 

repeat with i from 1 to length of tracknames 
    set nextline to item i of tracknames ¬ 
     & "::" & POSIX path of item i of locs ¬ 
     & "::" & item i of persistids 
    tell current application to write nextline & " 
" as «class utf8» to fileref 
end repeat 

close access fileref 

如果重複循環也吸引了性能,您可以誘使AppleScript以稍微不同的方式執行查找,而不會遭受相同的低效率。沒有實際測試過這個(不使用iTunes),但我認爲這應該這樣做:

tell application "iTunes" 
    tell every file track of library playlist 1 
     script performancekludge 
      property tracknames : its name 
      property locs : its location 
      property persistids : its persistent ID 
     end script 
    end tell 
end tell 

set thePath to (POSIX file "/tmp/songkong_itunes_model.txt") 
set fileref to open for access (thePath) with write permission 
set eof fileref to 0 

tell performancekludge 
    repeat with i from 1 to length of its tracknames 
     set nextline to item i of its tracknames ¬ 
      & "::" & POSIX path of item i of its locs ¬ 
      & "::" & item i of its persistids 
     write nextline & linefeed as «class utf8» to fileref 
    end repeat 
end tell 

close access fileref 

(懶得解釋的細節,但有上,如果你想讀的the book調整性能的一章進一步)。

+0

很好的答案+1。通過一次編寫文件或至少批量編寫文件,性能可能會得到改善...... – adayzdone

+0

感謝所有的信息,我會盡力,但我也對這個新的iTunes框架非常感興趣,儘管我很困惑它是否可以從applescript中調用,它與已從applescript –

+0

@PaulTaylor從doc中調用的類不同:「iTunes Library支持從沙盒應用程序訪問由iTunes提供的媒體。這個框架被認爲是iTunes 11的公共API。「iTunes Library Framework參考:https://developer.apple.com/library/mac/documentation/iTunesLibrary/Reference/iTunesLibraryFrameworkReference/_index.html#//apple_ref/ doc/uid/TP40012886 – 2014-01-19 03:13:52

相關問題