気にはなっていたのですが、このサイトの RDF を Safari で表示するとスクリプトが見にくいですね。スクリプトのインデントを CSS で整形しているのでこうなってしまうのですが...。どうやって回避しようか。と、悩んでみる振りをしていますが、このままでいく可能性大ですが...。
Database Events (1)、Database Events (2)、Database Events (3) と続いてきましたが、基本的なことはいったん終了して他のことを調べてみます。まずは、誰もが気になる(と思う)処理速度。SQLite をコマンドラインで使用すると何万件とあるデータをコンマ xxx 秒といった感じで即座に取り込んでくれます。
AppleScript から Database Events を利用するのであれば、そこまでの速度は、期待できません。ともあれ、やってみます。
次のようなスクリプトを用意して current date で時間を計ってみました。
--テスト用データを作成
tell application "Mail"
set dataList to {}
set theList to messages of mailbox 2
repeat with thisItem in (a reference to theList)
set end of dataList to {subject of thisItem, sender of thisItem, date sent of thisItem}
end repeat
end tell
tell application "Database Events"
--データベースを作成
make new database with properties {name:"Sample"}
save database "Sample"
tell database "Sample"
set cd to current date -- 計測開始
repeat with thisData in dataList
set theRecord to make new record with properties {name:item 1 of thisData}
tell theRecord
make new field with properties {name:"sender", value:item 2 of thisData}
make new field with properties {name:"date sent", value:item 3 of thisData}
end tell
end repeat
set n to (current date) - cd --計測終了
save
return n
end tell
end tell
Mail のメッセージでテストデータを作成し、それを新しく作成したデータベースに追加するスクリプトです。mailbox 2 の中には、1275 件のメールがありました。これらのデータを新規作成し、追加するのに 393 秒かかりました。約 6 分 30 秒です。ちょっと...遅くない?
いろいろ試してみたのですが、record の追加を一気に行うと速度的にはかなり遅くなります。どれぐらいのデータを一気に追加すると遅くなるか...。例えば、以下のようなスクリプトでデータ 1000 件を追加すると約 38 秒です。
tell application "Database Events"
make new database with properties {name:"Test"}
save database "Test"
tell database "Test"
repeat with i from 1 to 1000
make new record with properties {name:i as Unicode text}
end repeat
save
end tell
end tell
このスクリプトで数を変えていろいろ試してみましたが、せいぜい我慢できるのは 100 件ぐらいまでです。ただ、すでに record が 1000 個ある状態で新しく record を 1 件追加しても速度が遅いというわけではないです。このように繰り返しで一気に追加するのが遅いのです。
速度のことでいえば、record の削除でも同じことがいえます。削除は、delete 命令で行えるのですが、record が 5000 件あるときに
delete records
とすると、タイムアウトになります。いつまでたっても削除処理が完了しないのでどれぐらい時間がかかるのか分かりませんが、削除のときも一気に削除を行おうとすると、いつまでたっても反応が返ってこない、という状態に陥ります。ただ、これも単純に一件を削除するだけなら処理速度的に問題はありません。
record の数が多くなったときに処理が遅くなるのは新規作成、削除のときだけではありません。フィルタ参照も遅くなります。これも、番号参照などで record を決め打ちするなら最初の record でも最後の record でも真ん中の record でも速度的には変わりません。
tell application "Database Events"
tell database databaseFile
record 1 -- 変わらない
last record -- 変わらない
middle record -- 変わらない
some record -- 変わらない
records whose name of it contains "10" --データ数が多いと遅くなる
records 100 thru 200 --データの範囲が多いと遅くなる
end tell
end tell
上記のように番号参照、相対参照、中央参照、任意参照といった取り出すデータ数が 1 つのときは、速度低下がありません。が、フィルタ参照は、データ(record)の数が増えるとそれだけ速度が低下します。範囲参照も一気に取り出すデータ数が多くなると速度が低下します。
この処理速度の遅さは、SQLite に問題があるのではありません。Database Events の問題だと思います。今後、改良されてもう少しましになるといいのですが、今のところ CSV を一気に取り込むなんて処理は期待できそうにないです。データを追加、削除するのは sqlite3 で行うとしても、フィルタ参照が遅くなるなら Database Events の使い道って著しく限定されてしまうような...。
0 件のコメント :
コメントを投稿