web-dev-qa-db-ja.com

python)でマルチスレッド化されたtxtファイルを読み取ります

python(行をスキャンして用語を探す)でファイルを読み取って結果を書き込もうとしています-たとえば、各用語のカウンターです。これを大量に行う必要があります。ファイルの数(3000以上)。マルチスレッドで実行することは可能ですか?はいの場合、どのように実行しますか?

したがって、シナリオは次のようになります。

  • 各ファイルを読み取り、その行をスキャンします
  • 私が読んだすべてのファイルの同じ出力ファイルにカウンターを書き込みます。

2番目の質問は、読み取り/書き込みの速度が向上するかどうかです。

それが十分に明確であることを願っています。ありがとう、

ロン。

20
Ron D.

私は@aixに同意します、multiprocessingは間違いなく進むべき道です。 I/Oバウンドに関係なく、実行している並列プロセスの数に関係なく、非常に高速にしか読み取ることができません。しかし、簡単にsomeスピードアップがあります。

次のことを考慮してください(input /は、Project Gutenbergからのいくつかの.txtファイルを含むディレクトリです)。

import os.path
from multiprocessing import Pool
import sys
import time

def process_file(name):
    ''' Process one file: count number of lines and words '''
    linecount=0
    wordcount=0
    with open(name, 'r') as inp:
        for line in inp:
            linecount+=1
            wordcount+=len(line.split(' '))

    return name, linecount, wordcount

def process_files_parallel(arg, dirname, names):
    ''' Process each file in parallel via Poll.map() '''
    pool=Pool()
    results=pool.map(process_file, [os.path.join(dirname, name) for name in names])

def process_files(arg, dirname, names):
    ''' Process each file in via map() '''
    results=map(process_file, [os.path.join(dirname, name) for name in names])

if __name__ == '__main__':
    start=time.time()
    os.path.walk('input/', process_files, None)
    print "process_files()", time.time()-start

    start=time.time()
    os.path.walk('input/', process_files_parallel, None)
    print "process_files_parallel()", time.time()-start

これをデュアルコアマシンで実行すると、顕著な(ただし2倍ではない)スピードアップがあります。

$ python process_files.py
process_files() 1.71218085289
process_files_parallel() 1.28905105591

ファイルがメモリに収まるほど小さく、I/Oバウンドではない処理を実行する必要がある場合は、さらに改善されるはずです。

18
Austin Marshall

はい、これを並行して行うことができるはずです。

ただし、Pythonでは、複数のスレッドで並列処理を実現するのは困難です。このため、並列処理を行うには、 multiprocessing がデフォルトの選択肢として適しています。

どのようなスピードアップが期待できるのかはわかりません。これは、ワークロードのどの部分を並行して実行できるか(より良い)、およびどの部分を連続して実行する必要があるか(より少ない方が良い)によって異なります。

2
NPE