Database Events (4)

気にはなっていたのですが、このサイトの 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 秒です。

Script Editor で開く

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 件のコメント :

コメントを投稿