2011-06-28 17 views
2

〜40MBのgzip形式のテキストファイルを読み込んで処理する必要があります。また、ボリュームを他のユーザーも使用するため、I/Oオーバーヘッドを最小限に抑えて高速に処理する必要があります。私はこの作業のためにこれ見つけた最速の方法は、次のようになります。mmapをpopenで使用する

def gziplines(fname): 
    f = Popen(['zcat', fname], stdout=PIPE) 
    for line in f.stdout: 
     yield line 

、その後:

for line in gziplines(filename) 
    dostuff(line) 

が、私がやりたいものを(?これは高速です IF)ものです悲しいことに

def gzipmmap(fname): 
    f = Popen(['zcat', fname], stdout=PIPE) 
    m = mmap.mmap(f.stdout.fileno(), 0, access=mmap.ACCESS_READ) 
    return m 

、私はこれをしようとすると、私はこのエラーを取得:

このような

にもかかわらず、私は試してみてください。

だから、
>>> f.stdout.fileno() 
4 

、私はここで何が起こっているかの基本的な誤解があると思います。 :(

二つの質問は次のとおりです。

1)は、このMMAPは、処理のためにメモリにファイル全体を置くことで、より高速な方法だろうか?

2)これをどのように達成できますか?

ありがとうございました。皆さん、ここにいる皆さんは、既に非常に役立っています! mmap(2) manページから 〜ニック

+0

あなたのジェネレータの解決策は、とにかくmmapを使うよりはっきりしています。外部プログラムを呼び出すのではなく、Pythonの標準gzipライブラリを使ってみましたか? http://docs.python.org/library/gzip.html –

答えて

3

ENODEV The underlying file system of the specified file does not sup- 
      port memory mapping. 

あなたは、実際のファイルや匿名のスワップ領域のみをストリームのmmapすることはできません。ストリームからメモリに読み込む必要があります。

+0

ありがとうございます。 1年後にこれに戻って... mmapと他のすべてのことをもっとよく理解している! – Nik

1

パイプはmmapableではありません。

case MAP_PRIVATE: 
     ... 
if (!file->f_op || !file->f_op->mmap) 
     return -ENODEV; 

パイプのファイル操作にはmmapフックが含まれていません。

関連する問題