AppleScriptでリスト型変数の末尾にアイテムを追加する場合には、
set aList to {1,2,3,4}
set the end of aList to 5
aList
--> {1,2,3,4,5}
みたいな決まりきった書き方がある。何の疑問も持たずにそのまま書いていた。
これを、先頭に要素を追加する場合にはどーしたものかと思い、冗談半分に、
set aList to {2, 3, 4, 5}
set the beginning of aList to 1
aList
なんて書いてみた。実行したら期待どおりになって驚いた。こんな命令知らなかった(汗) MLの過去ログを全文検索で探してみたら、たしかにごくまれに登場してきている。
--> {1,2,3,4,5}
知らなくても困らなかったというのは、そういう処理を自前で書いていたからなのだが……命令で持っているならこっちの方が速いことだろう。
set the end of……については、リスト項目の順次連結が高速ということで愛用しているわけであって、beginningはどうなんだろうというのが次の疑問点。
そこでMacBook CoreDuo 1.8GHzで実験。
set sTime to current date
set aList to {}
repeat with i from 1 to 1000
set aList to aList & i
end repeat
set eTime to current date
set elTime to eTime - sTime
display dialog elTime
set sTime to current date
set aList to {}
repeat with i from 1 to 1000
set the end of aList to i
end repeat
set eTime to current date
set elTime to eTime - sTime
display dialog elTime
単純にset aList to aList & i みたいに連結した場合と、set the end ofを使った場合とでは、後者のほうが15倍高速という結果に(8,000アイテム連結時)。
また、単純前方連結とset the beginning ofでは……後方連結ほど差はつかなかったものの、それでもbeginningのほうが8倍高速(8,000アイテム連結時)という結果。
「set the end of」や「set the beginning of」を用いないのは宝の持ち腐れであり、リスト型変数の連結は基本的に後ろに行うほうが速度的に有利だ、というのが結論。いままで無意識に組んでいた内容を証明する結果となった。
久しぶりにこの種の計測をやってみたが、「Intel Macはやっ!」というのが正直な感想。これが、雑誌の記事向けに資料を作るのであれば、10回計測して平均値を取得するとか、そのぐらいはやっておく必要があるところだが、概算値が分かればいいぐらいのレベルなので、まあいいだろう。8コアのXeon搭載Mac Proで速度計測を行えたら面白いのだが……。
最近は、AppleScriptでもプログラムが複雑化して常識的に数万レコードのデータを変数の上で操作していたりするので気付かなかったものの、1,000アイテムぐらいの連結だと瞬殺。
数値ではなく文字列連結だともうちょっと遅くなるはずだ。