2012-05-30T22:33:30+09:00

Finder のコピー vs シェルの cp コマンド

AppleScript でファイルをコピーすることを考える。AppleScript として、Finder にイベントを送るのが、もっとも正当な方法だとおもう。もう一つは、do shell script で cp コマンドを実行することだ。

どっちが速い、次のコードで比較してみた。空ファイルをコピーしているから、シェルの起動にかかる時間と、イベントのやり取りする時間の比較になっている(と思う)。ちなみに、実行には LapTime.osax が必要です。

do shell script "touch $HOME/testfile"

tell application "Finder"
set source to item "testfile" of (path to home folder) as alias
set destination to (path to documents folder)
end tell

set tm to start timer

do shell script "cp " & source's POSIX path's quoted form & space & destination's POSIX path's quoted form & ";" & "rm " & (destination's POSIX path & "testfile")'s quoted form

lap time tm

tell application "Finder"
duplicate source to destination
end tell

lap times of (time records of tm)
--result : {13.662109375, 48.06005859375}

上記のサンプルコードでの結果は、

となった。環境は、Mac OS X 10.6.8, Mac Book Pro (2.66 GHz Core 2 Duo).

cp コマンドの方が圧倒的に速いぜ。

AppleScriptor としては、少々しゃくだけどアプリケーションへのイベントの送信より、シェルコマンドの起動のほうがずっと効率的ということになる。でも、シェルスクリプトをガシガシ混ぜるのは、コードとしてすごく煩雑になる。そこで、シェルコマンドをラップしたモジュールを作るのが僕のアプローチ。

例えば、XFile を使えば、ファイルのコピーは次のように書ける。

property XFile : module
boot (module loader) for me

do shell script "touch $HOME/testfile"

set source to XFile's make_with(path to home folder)'s child("testfile")
source's copy_to("Documents")

エレガントだろぅ〜。上記のスクリプトの実行には、XModulesCore をインストールするのが手っ取り早いです。

実は、このポストを書いていて、XFile の copy_to はすごく遅いことに今更ながら気付いた。info for コマンドを without size を付けないで、実行していることが原因だ。次のバージョンでは、速くするぜ。