私はいくつかの動的計画法コードを実行していて(コラッツの予想= Pをブルートフォースで反証しようとしました)、すでに計算したチェーンの長さを格納するためにdictを使用していました。明らかに、ある時点でメモリが不足しました。 dict
のバリアントを使用して、スペースが不足したときにそれ自体の一部をディスクにページアウトする簡単な方法はありますか?明らかに、メモリ内の辞書よりも遅くなり、おそらく私のハードドライブのスペースを使い果たしてしまうでしょうが、これはそれほど無駄ではない他の問題にも当てはまる可能性があります。
ディスクベースの辞書はほとんどデータベースであることに気付いたので、sqlite3を使用して手動で実装しましたが、スマートな方法ではなく、DB内のすべての要素を一度に1つずつ検索しました...約300倍遅くなりました。
自分のdictのセットを作成し、一度に1つだけをメモリに保持し、それらを効率的な方法でページングする最も賢い方法はありますか?
Hash-on-diskは通常、Berkeley DBまたは同様のもので対処されます-いくつかのオプションが Python Data Persistenceドキュメント にリストされています。インメモリキャッシュを前に置くこともできますが、最初にネイティブパフォーマンスに対してテストします。オペレーティングシステムのキャッシュを設定すると、ほぼ同じになる可能性があります。
サードパーティ shove モジュールも一見の価値があります。単純なdictのようなオブジェクトであるという点で、shelveと非常に似ていますが、さまざまなバックエンド(ファイル、SVN、S3など)に格納でき、オプションの圧縮を提供し、スレッドセーフですらあります。とても便利なモジュールです
from shove import Shove
mem_store = Shove()
file_store = Shove('file://mystore')
file_store['key'] = value
shelve モジュールがそれを行う可能性があります。とにかく、テストは簡単なはずです。の代わりに:
self.lengths = {}
行う:
import shelve
self.lengths = shelve.open('lengths.shelf')
唯一の落とし穴は、棚の鍵は文字列でなければならないので、交換する必要があるということです
self.lengths[indx]
と
self.lengths[str(indx)]
(Charles Duffyの投稿へのコメントによると、キーは単なる整数であると想定しています)
メモリには組み込みのキャッシュはありませんが、とにかくオペレーティングシステムがそれを行う可能性があります。
[実際、それは完全に真実ではありません。作成時に引数 'writeback = True'を渡すことができます。これの目的は、リストやその他の変更可能なものをシェルフに正しく保存することを確認することです。ただし、副作用として、辞書全体がメモリにキャッシュされます。これはあなたに問題を引き起こしたので、それはおそらく良い考えではありません:-)]
前回このような問題に直面したとき、dictではなくSQLiteを使用するように書き直し、パフォーマンスが大幅に向上しました。そのパフォーマンスの向上は、少なくとも部分的にはデータベースのインデックス作成機能によるものでした。アルゴリズムに応じて、YMMV。
__getitem__
および__setitem__
でSQLiteクエリを実行するシンラッパーは、記述するコードがそれほど多くありません。
少し考えれば、 shelve module でやりたいことができるようです。
gvRからこの質問への回答を読んでください;) Pythonを使用して2MBのRAM RAM $ ===を使用して100万の32ビット整数をソートする
棚が遅すぎると思い、sqliteを使用して独自のdictをハックしようとしたことを読みました。
別の人もこれをしました:
http://sebsauvage.net/python/snyppets/index.html#dbdict
それはかなり効率的だと思われます(そしてsebsauvageはかなり良いコーダーです)。多分あなたはそれを試してみることができますか?
次に取得される可能性が最も高いアイテムを知るためのヒューリスティックがある場合は、一度に複数のアイテムを持参する必要があります。また、Charlesが言及しているようなインデックスを忘れないでください。
私はまだ試していませんが Hamster DB は有望で、Pythonインターフェースを持っています。
単純なユースケースの場合 sqlitedict が役立ちます。ただし、はるかに複雑なデータベースがある場合は、より賛成の回答の1つを試してみるとよいでしょう。