Python セット コレクションを使用して、一意のオブジェクトを格納します。すべてのオブジェクトはオーバーライドさ__hash__
れています。__eq__
このセットには、200,000 近くのオブジェクトが含まれています。セット自体は 4 GB 近くのメモリを必要とします。5 GB を超えるマシンでは正常に動作しますが、利用可能な RAM が 3 GB しかないマシンでスクリプトを実行する必要が生じました。
スクリプトを C# に書き直しました。実際には、同じソースから同じデータを読み取り、それをセット (HashSet) の CLR アナログに配置すると、4 GB ではなく 350 MB 近くかかりましたが、スクリプトの実行速度は比較的同じでした (約 40 秒) しかし、Python を使用する必要があります。
Q1: Python には「ディスク永続」セットまたはその他の回避策がありますか? hash/eq メソッドで使用される「キー」データのみをメモリに格納でき、それ以外はすべてディスクに永続化できると思います。または、Python には、システムで使用できるよりも多くのメモリを消費する可能性があるオブジェクトの一意のコレクションを作成するための他の回避策があるかもしれません。
Q2: あまり実用的ではない質問: なぜ python set は set にこれほど多くのメモリを必要とするのですか?
64ビットのUbuntu 12.10で標準のPython 2.7.3を使用しています
ありがとうございました。
Update1: スクリプトの機能:
多くの半構造化された JSON ドキュメントを読み取る (各 JSON は、それに関連する集約オブジェクトのコレクションを持つシリアル化されたオブジェクトで構成されます)
各 JSON ドキュメントを解析して、メイン オブジェクトと集約されたコレクションのオブジェクトを取得します。解析されたすべてのオブジェクトはセットに格納されます。セットは、一意のオブジェクトのみを格納するために使用されます。最初にデータベースを使用しましたが、データベースの一意の制約は x100-x1000 遅く動作します。すべての JSON ドキュメントは、1 ~ 8 の異なるオブジェクト タイプに解析されます。各オブジェクト タイプは独自のセットに格納され、一意のオブジェクトのみがメモリに保存されます。
セットに格納されたすべてのデータは、一意の制約を持つリレーショナル データベースに保存されます。各セットは別々のデータベース テーブルに格納されます。
非構造化データを取得し、JSON ドキュメント内の集約されたオブジェクト コレクションから重複を削除し、構造化データをリレーショナル データベースに保存するスクリプトの全体的な考え方。
更新 2:
2 delnan: コードのすべての行にコメントを追加して、他のすべてのスタッフ (データの取得、解析、反復) を同じに保つ別のセットに追加しました - スクリプトが必要とするメモリは 4 GB 少なくなりました。
つまり、これらの 200K オブジェクトがセットに追加されると、大量のメモリを消費し始めるということです。オブジェクトは、TMDB からの単純な映画データです。ID、ジャンルのリスト、俳優、監督のリスト、その他の多くの映画の詳細、および場合によっては Wikipedia からの大きな映画の説明です。