2009-05-28 9 views
3

私はいくつかのコードに取り組んでいます。私の通常のアプローチは、問題のすべてを最初に解決し、問題を解決するために必要なコードとループを作成し、コードを再利用することを期待したら、私は機能を作成するためにグループ化する必要があると思います。コードが関数にラップされているときにメモリ効率が向上していますか?

私は、関数を作成して呼び出すことは、コードの行を記述してコンテナを削除するよりもはるかに効率的であるように見えました。例えば

def someFunction(aList): 
    do things to aList 
    that create a dictionary 
    return aDict 

>>do things to alist 
>>that create a dictionary 
>>del(aList) 

よりも最後に多くのメモリを解放しているようだが、この予想される動作ですか?この機能は、PFの使用を実行するfilingsListは約8万行を有し、約100メガバイトの増加を示す終了する

EDITは、例えば、コード

を加えました。私が代わりにこれを実行した場合

def getAllCIKS(filingList): 
    cikDICT=defaultdict(int) 
    for filing in filingList: 
     if filing.startswith('.'): 
      del(filing) 
      continue 
     cik=filing.split('^')[0].strip() 
     cikDICT[cik]+=1 
     del(filing) 
    ciklist=cikDICT.keys() 
    ciklist.sort() 
return ciklist 

allCIKS=getAllCIKS(open(r'c:\filinglist.txt').readlines()) 

は、私はほとんど400メガバイト

cikDICT=defaultdict(int) 
for filing in open(r'c:\filinglist.txt').readlines(): 
    if filing.startswith('.'): 
     del(filing) 
     continue 
    cik=filing.split('^')[0].strip() 
    cikDICT[cik]+=1 
    del(filing) 

ciklist=cikDICT.keys() 
ciklist.sort() 
del(cikDICT) 

EDIT 私はいくつかのより多くの今日こので遊んでてきたの増加を示します。私の焦点はPF使用法に基づいているので、私の観察と質問は少し洗練されていなければなりません。残念ながら、私は他のタスクの間でこれを突き止めることができます。しかし、私は参考文献とコピーについて不思議に思っています。リストから辞書を作成すると、辞書コンテナはリストから来た値のコピーを保持するか、リストの値への参照を保持しますか?私の賭けは値が参照の代わりにコピーされるということです。

もう1つ気づいたのは、GCリストのアイテムが、削除されたコンテナのアイテムだということです。それは理にかなっていますか?私はリストを持っていて、リスト内の各アイテムが[(aTuple)、anInteger、[別のリスト]]であったとします。私がgcオブジェクトを操作する方法を学習し始めたとき、リストが強制的に削除されたにもかかわらず、私が覚えていないメソッドに0 & 2の値を渡したにもかかわらず、それらを削除しようとする。

人々が共有している洞察を高く評価します。残念ながら、私は常にフードの中で物事がどのように機能するかを理解することに興味があります。

+0

リリースされたメモリ量はどのように測定していますか? – Joe

+0

WindowsのタスクマネージャでPFの使用状況を見ています。 – PyNEwbie

+0

@PyNEwbie:実際のコードを含むようにサンプルを編集できますか?それは本当に起こっていることを追跡するために長い道のりを行くことができます。 –

答えて

0

一部の余分なメモリは関数から返っても解放されますが、最初はその関数を呼び出すために割り当てられたメモリとまったく同じです。どんな場合でも - 多量の相違がある場合、それはランタイム状態のアーチファクトであり、本当に心配すべきではありません。メモリが不足している場合、問題を解決する方法は、b-treeなどのものを使用してディスク上にデータを保持する(またはデータベースを使用する)か、メモリを少なくするアルゴリズムを使用することです。また、大規模なデータ構造を不必要にコピーすることに注意してください。

関数を作成する際の実際のメモリ節約は、短期間のメモリ内にあります。何かを関数に移動させることによって、細目の一部をカプセル化することによって、覚えておく必要がある詳細の量を減らすことができます。

+0

あなたは、解放されたメモリは関数内のコード行を処理するために必要なメモリであり、それは正しくないと言います。私はgcが関数によって異なって扱われると思っています – PyNEwbie

+1

私はそれが心配する価値がないと言っています。 gcがその仕事をするようにしてください。メモリを解放する正確なタイミングはそれほど重要ではありません。メモリが足りなくなり、メモリが解放されると、メモリは解放されます。 – Eclipse

1

提供されたPython garbage collector interfaceを使用すると、2番目のケースで何が残っているかをさらに詳しく調べることができます。具体的には、gc.get_objects()をチェックして未収集のものを確認するか、gc.garbageを参照して参照サイクルがあるかどうかを確認することができます。

+0

はい、私はそれらと遊んでいます。その説明は少し複雑ですが、コードの行を送信するよりも、関数を使用しているときにgcが良いと示唆しています。 – PyNEwbie

3

関数内にローカル変数がいくつか使用されている可能性があります。関数の終わりに参照カウントによって暗黙的に解放され、コードセグメントの最後に解放されませんでしたか?

+0

これは実際のコードを見ることなく私の推測になります。 –

0

不要な変数を取り除くためにコードを再設計する必要があります(瞬時に解放されない可能性があります)。次のスニペットはどうですか?

myfile = file(r"c:\fillinglist.txt") 
ciklist = sorted(set(x.split("^")[0].strip() for x in myfile if not x.startswith("."))) 

編集:この回答が否定的な理由で投票された理由は分かりません...おそらく短いですか?あるいは、投票した男が、このワンライナーが、不必要な一時的な容器を作成せずに問題のコードと同じことを理解できなかったためでしょうか?

ため息...

0

私は特にdeepcopyを見て私を指示する答えは、私はいくつかの辞書の行動について考えさせ、リストや解答のコピーについては、別の質問をしました。私が経験していた問題は、辞書がリストへの参照を保持しているため、元のリストは決してガベージコレクションされないという事実と関連していました。私はPython Docsのweakrefに関する情報を使用する必要があります。

辞書で参照されるオブジェクトは生き残っているようです。私は、関数から辞書をプッシュするプロセスがコピープロセスを強制し、オブジェクトを殺すとは思う(しかし分かっていない)。これは完全ではありません、私はもう少し研究をする必要があります。

関連する問題