2

処理したいデータが DB に保存されています。DB アクセスは非常に遅いため、処理の前にすべてのデータをディクショナリにロードすることにしました。ただし、格納されているデータのサイズが大きいため、メモリ不足エラーが発生します (2 ギガ以上が使用されていることがわかります)。そこで、ディスク データ構造を使用することにしました。そして、shelve を使用するオプションがあることがわかりました。これが私がしていることです(疑似pythonコード)

def loadData():
    if (#dict exists on disk):
        d = shelve.open(name)
        return d
    else:
        d = shelve.open(name, writeback=True)
        #access DB and write data to dict
        # d[key] = value 
        # or for mutable values
        # oldValue = d[key]
        # newValue = f(oldValue)
        # d[key] = newValue 
        d.close()
        d = shelve.open(name, writeback=True)
        return d

いくつか質問があります。

1) 本当に writeBack=True が必要ですか? それは何をするためのものか?

2) データがディスクに書き込まれるタイミングを制御していないため、引き続き OutofMemory 例外が発生します。それ、どうやったら出来るの?数回繰り返すごとに sync() を実行しようとしましたが、それも役に立ちませんでした。

ありがとう!

4

2 に答える 2

10

writeback=Trueこれまでにフェッチされたアイテムをシェルフに強制的にメモリ内に保持し、シェルフが閉じられたときにそれらを書き戻します。そのため、より多くのメモリを消費し、閉じるのが遅くなります。

パラメーターの利点は、ミューテーターがメソッドである変更可能なアイテムのコメントに表示される歪んだコードが必要ないことです。

shelf['foobar'].append(23)

shelfキーのアイテムがもちろんリストであると仮定すると、機能します(ライトバックを有効にして開いた場合)。'foobar'一方、ライトバックなしで開いた場合は、何も操作しません(ディスク上のアイテムは変更されません)shelf-後者の場合、実際にコーディングする必要があります

thelist = shelf['foobar']
thelist.append(23)
shekf['foobar'] = thelist

あなたのコメントの精神の中で - これは文体的にはやや残念です。

ただし、メモリに問題があるため、この怪しげな書き戻しオプションを使用しないことを強くお勧めします。私はそれを提案して最初に実装したので、それを「疑わしい」と呼ぶことができると思いますが、それは何年も前のことであり、私はそれをしたことをほとんど後悔しています. dicts で動作するように最初に書かれたコードを移動する際の優雅さと便利さを可能にします (これは 2 番目ではなく最初のイディオムを使用するため、トレースバックなしでシェルフで使用できるようにするには書き直す必要があります)。ああ、すみません、当時良い考えに思えました。

于 2010-02-04T04:03:09.097 に答える
0

ここでは、モジュールを使用するのsqlite3がおそらく最良の選択です。いずれにせよ、そのメモリフットプリントはpythonオブジェクトを使用するよりも少し小さいかもしれないので、とにかくメモリ内で完全にsqliteを使用できるかもしれません。shelveとにかく使用するよりも一般的には良い選択です。shelveこれはpickleめったにあなたが望むものではありません。

地獄、既存のデータベース全体を sqlite データベースに変換するだけで済みます。sqlite は素晴らしく高速です。

于 2010-02-04T03:24:50.667 に答える