RAMには多すぎると思います。可能であれば、1 つの for ループでアクションを実行し、メモリ効率のために反復を最適化する必要があります。
fp.readlines()
ええと、それはファイルのすべての行を一度に読み取るため、その内容はすべてメモリにあります。ファイルの内容を辞書に変換する方法の詳細についてはわかりません。ただし、ファイル内の行に依存している場合は、反復ステップごとに新しい行を生成するファイルを単純に反復することができます。
for line in fp:
# ...
ただし、ファイルのすべての情報を再び辞書に保存すると、同じ問題に再び直面することになります。
(可能であれば) 重複をチェックしてメモリに保存したデータを最適化すると、CPU が集中的に使用されますが、メモリ使用量を下げる必要がある場合があります。
コンシステント ストレージとジェネレーターの違いは、これら 2 つのスニペットが同じ操作を実行した後に明らかになるはずですが、前者は後者よりもメモリを集中的に使用します。iterate_to
は関数を正確に複製したrange/xrange
ものであり、単に実証的な目的を果たしていることに注意してください。
def iterate_to(num):
list_ = []
for i in xrange(num):
list_.append(i)
return list_
def operate_on(num):
list_ = []
for i in iterate_to(num):
x = (i ** i + 5) / (i * 2)
list_.append(x)
return list_
print sum(operate_on(1000000))
関数はsum
によって返されるリストの各要素を合計しoperate_on
ますが、それぞれ1000000 エントリ(!!) を持つ 2 つのリストはメモリ内で一貫しています。メモリ効率をもう少し向上させることができるとすでに考えているかもしれません。
def iterate_to(num):
for i in xrange(num):
yield i
def operate_on(num):
for i in iterate_to(num):
x = (i ** i + 5) / (i * 2)
yield x
print sum(operate_on(1000000))
この例では、と関数のyield
両方をジェネレーター関数にするために式が使用されています。反復中、各反復ステップで、反復の次の要素は、以前に構築されたアイテムのコレクションに依存するのではなく、直接計算されます。
ジェネレーターの詳細については、こちらをご覧ください。iterate_to
operate_on