2012-07-05 25 views
15

私は約50GBのテキストファイルを持っており、最初の数文字をチェックしています。毎回Pythonファイルを開いたり閉じたりしています。処理が完了するまで開いたままにしておきます。

たとえば、 私の入力が含まれています

cow_ilovecow 
dog_whreismydog 
cat_thatcatshouldgotoreddit 
dog_gotitfromshelter 
............... 

だから、私は牛、犬と猫でそれらを処理したい(約200)カテゴリ ので、

if writeflag==1: 
    writefile1=open(writefile,"a") #writefile is somedir/dog.txt.... 
    writefile1.write(remline+"\n") 
    #writefile1.close() 

ので、最善の方法は、私は、何をすべきです閉じる?そうでなければ、私はそれを開いたままにして、writefile1=open(writefile,"a")は正しいことですか?

答えて

28

あなたは間違いなくオープン/クローズがはるかに高価

は考えてみているファイル、/

できるだけ少ないとしてファイルを閉じる開くしようとする必要があります2つのコード・ブロック:

f=open('test1.txt', 'w') 
for i in range(1000): 
    f.write('\n') 
f.close() 

for i in range(1000): 
    f=open('test2.txt', 'a') 
    f.write('\n') 
    f.close() 

秒1は、おかげで、私は常にオープンファイルがメモリにファイル全体をロードするのに0.309s

+0

偉大な、テストしたはずです、これは非常にいくつかのオープン/クローズステートメントを作成する意味があります – Ananta

1

全体を開いてください!それ以外の場合は、書き込みが完了したことをシステムに伝え、バッファリングする代わりにディスクにフラッシュすることを決定する可能性があります。明らかな理由のために、nディスク書き込みは、ディスク書き込みよりもはるかに高価です。

ファイルに追加して上書きしない場合は、aが正しいモードです。

+0

をとりながら、最初のものは0.025sをとります。 – Ananta

4

、それはあなたのために開いているファイルをおこうとあなたがwithブロックの外出一度ファイルを閉じますので、withブロック内のすべての操作を行い、それが自動的にファイルを閉じ、withステートメントを使用します。

with open(inputfile)as f1, open('dog.txt','a') as f2,open('cat.txt') as f3: 
    #do something here 

EDIT: あなたはより良いオプションがあるあなたのコードのコンパイルは、その後withを使用する前に、可能なすべてのファイル名を使用すると、あなたがない場合は、代わりのあなたのアプローチを使用することがわかっている場合ファイルを閉じることができますflushファイルにデータを使用してwritefile1.flush()

+0

'with'ステートメントは、入力の各接頭辞のために新しいファイルを開いていると、ちょっとしたことがあります。コンパイル時にすべての接頭辞が分かっているかどうかは不明です。 – geoffspear

+0

@Wooble良い点! 'with'を使うと、ランタイムの前にすべてのファイル名を知る必要があることを意味しますが、彼がすべてのファイル名を知っていれば、そのような場合は' with'が良いオプションです。 –

+1

また、200のカテゴリでは、おそらく200の変数ではなくファイルの辞書が最適な解決策です。 – geoffspear

-1

IO操作が多すぎる時間を消費します。ファイルを開いて閉じます。

両方のファイル(入力と出力)を開くと、はるかに高速です。テキスト処理用に10MBのサイズのメモリバッファを使用して、これを出力ファイルに書き込みます。たとえば、次のようにしても読み出し/書き込みファイルと比較するので

file = {} # just initializing dicts 
filename = {} 
with open(file) as f: 
    file['dog'] = None 
    buffer = '' 
    ... 
    #maybe there is a loop here 
    if writeflag: 
     if file['dog'] == None: 
      file['dog'] = open(filename['dog'], 'a') 
     buffer += remline + '\n' 
    if len(buffer) > 1024*1000*10: # 10MB of text 
     files['dog'].write(buffer) 
     buffer = '' 

for v in files.values(): 
    v.close() 
+0

私はこの方法で行くかもしれませんが、私はそれが各プレフィックスのために異なるバッファであるべきだと思います。元のファイルの特定の行を処理した後にすべてのファイルに書き込む方が適切でしょうか? – Ananta

+0

-1、それはあなたのアプリケーションコードで何もすべきではありません。オペレーティングシステムは、読み書き操作を自由にすることができます(つまり、操作ごとにファイルを閉じたり開いたりしないでください)。バッファに文字列を使うのは、リストに比べてかなり高価です。 – ThiefMaster

+0

@ThiefMaster単純なベンチマークを作成したところ、文字列を含むバッファを使用すると、ioを直接使用するよりも13%高速で、リスト付きバッファを使用するよりも5%高速でした。実際、Pythonの文字列操作は実際に最適化されています。ここでコードを確認できます:http://paste.kde.org/513206/ –

関連する問題