7

私は、ファイルのセットに対してかなり大きなクエリを含む可能性のあるPythonコマンドラインユーティリティを開発しています。これはかなり有限のクエリリストです(インデックス付きDB列を考えてください)。処理中のパフォーマンスを向上させるために、毎回ファイルシステムをヒットするのではなく、並べ替え/構造化リスト、マップ、ツリーを1回生成し、それらを繰り返しヒットすることができます。

ただし、これらのキャッシュはプロセスが終了すると失われ、スクリプトを実行するたびに再構築する必要があるため、プログラムの実行時間が大幅に増加します。コマンドの複数の実行間でこのデータを共有するための最良の方法を特定したいと思います。これは、同時に、次々に、または実行間で大幅な遅延が発生する可能性があります。

要件:

  • 高速である必要があります-実行ごとの処理は最小限に抑える必要があります。これには、ディスクIOとオブジェクトの構築が含まれます。
  • OSにとらわれない必要があります(または、少なくともUnix / Windowsで同様の基本的な動作にフックできる可能性があります)。
  • かなり複雑なクエリ/フィルタリングを許可する必要があります-キー/値マップは十分ではないと思います
  • 最新である必要はありません-(簡単に)古いデータは完全に問題ありません。これは単なるキャッシュであり、実際のデータは個別にディスクに書き込まれます
  • MySQLやMemCachedのような重いデーモンプロセスを使用できません-インストールコストを最小限に抑えたいので、各ユーザーにこれらのサービスのインストールを依頼するのは多すぎます。

環境設定:

  • 可能であれば、長時間実行されるデーモンプロセスは一切避けたいと思います。
  • キャッシュをすばやく更新できるようにしたいのですが、更新時にキャッシュ全体を再構築することは世界の終わりではありません。高速読み取りは高速書き込みよりもはるかに重要です。

私の理想的なファンタジーの世界では、実行の合間にPythonオブジェクトを直接保持できます。これは、シングルトンデータストアオブジェクトを共有するJavaスレッド(Tomcatリクエストなど)のようなものですが、それは不可能かもしれません。でも、それに近づくことができれば、それだけ良いです。

候補者:

  • メモリ内のSQLite

    SQLite自体は、ディスクに支えられているため、実行のたびにファイルから読み取る必要があるため、私のユースケースには十分な速度ではないようです。おそらくこれは見た目ほど悪くはありませんが、データベースを永続的にメモリに保存する必要があるようです。SQLiteでは、DBがメモリをストレージとして使用できますが、これらのDBはプログラムの終了時に破棄され、インスタンス間で共有することはできません。

  • mmapでメモリにロードされたフラットファイルデータベース

    スペクトルの反対側では、キャッシュをディスクに書き込んでから、mmapを使用してメモリにロードし、別々の実行間で同じメモリスペースを共有できます。ただし、すべてのプロセスが終了した場合にmmapがどうなるかはわかりません。mmapが最終的にメモリからフラッシュされても問題ありませんが、ユーザーがコマンドを次々に実行してキャッシュを再利用できるように、mmapを少し(30秒?数分?)保持したいと思います。 この例は、開いているmmapハンドルが必要であることを示しているようですが、メモリマップトファイルがメモリから削除され、ディスクからリロードする必要がある場合の正確な説明は見つかりませんでした。

    終了後にmmapオブジェクトがくっついていれば、これを実装できると思いますが、レベルが非常に低く感じられ、誰かがすでによりエレガントなソリューションを実装していると思います。SQLiteを再構築していることに気付くためだけに、これを構築し始めたくありません。一方で、非常に高速であるように感じられ、特定のユースケースを考慮して最適化を行うことができました。

  • Processingを使用してプロセス間でPythonオブジェクトを共有する

    Processingパッケージは、「...共有メモリを使用してプロセス間でオブジェクトを共有できる」ことを示しています。残りのドキュメントを調べてみると、この動作についてこれ以上言及されていませんが、それは非常に有望に聞こえます。誰かが私にもっと情報を教えてもらえますか?

  • RAMディスクにデータを保存する

    ここでの私の懸念はOS固有の機能ですが、RAMディスクを作成して、好きなように読み取り/書き込みを行うことができます(SQLite?)。fs.memoryfsパッケージは、複数のOSで動作する有望な代替手段のように見えますが、コメントはかなりの数の制限を暗示しています。

pickleはPythonオブジェクトを保存するための効率的な方法であるため、あらゆる種類の手動データストレージよりも速度が優れている可能性があります上記のオプションのいずれかにピクルスを引っ掛けることはできますか?フラットファイルやSQLiteよりも優れているでしょうか?

これに関連する質問がたくさんあることは知っていますが、かなり掘り下げてみたところ、複数のコマンドラインの実行に関する質問に直接対応するものは見つかりませんでした。

私は完全に認めます、私はこれをかなり考えすぎているかもしれません。私は自分の選択肢の感触をつかもうとしているだけで、それらが価値があるかどうかを調べています。

手伝ってくれてどうもありがとう!

4

1 に答える 1

7

私はおそらくうまくいくかもしれない最も単純なことをするでしょう。...あなたの場合、これはおそらくピクルスファイルにダンプすることです。十分な速度が得られない場合は、もっと複雑なもの(memcachedやSQLiteなど)を試してください。ドナルド・クヌースは「時期尚早の最適化はすべての悪の根源です」と言います!

于 2012-06-09T17:55:47.813 に答える