2

Python を使用して多数のファイルの各行を読み取って変更しようとしています。各ファイルには数千から数十万の行があるため、各ファイルは、処理された場合、別のファイルの後にのみ処理されます。次のようなファイルを読み込もうとしています:

csvReader = csv.reader(open("file","r")
for row in csvReader:
    handleRow(row)

時間を節約するために、マルチスレッドを使用して、異なるスレッドを並列に使用して各ファイルを読み取りたいと考えています。それが役立つかどうか、およびそれを実装する方法を誰かが指摘できますか?

4

2 に答える 2

3

役に立つかもしれないし、役に立たないかもしれません。すべてのファイルが同じドライブにあり、すでにドライブを可能な限り高速にプッシュしている場合、多重化は物事を遅くするだけです。ただし、I/O を最大限に活用していない場合は、速度が向上します。

それを行う方法に関しては、それは簡単です。パス名を受け取る関数でコードをラップしてから、concurrent.futures.ThreadPoolExecutor または multiprocessing.dummy.Pool を使用します。1 行のコードで、反復可能なパス名全体に関数をマップします。

with ThreadPoolExecutor(4) as executor:
    executor.map(func, paths)

もう 1 つ: I/O を最大化できない理由が、各行で CPU を使いすぎているためである場合、Python では (GIL のため) スレッドは役に立ちませんが、使用することはできます。プロセス - まったく同じコードですが、ProcessorPoolExecutor を使用します。

于 2013-10-19T21:21:02.493 に答える
1

おそらくボトルネックは I/O であるため、マルチスレッドは役に立ちません。とにかく、試すのは簡単です: 次のコードは、指定された文字列関数を各行に適用し、指定されたパスに新しいファイルを書き込むことにより、現在のディレクトリにあるすべてのファイルを、ファイルごとに 1 つのスレッドで処理します。

from threading import Thread
from os import listdir
from os.path import basename, join, isfile

class FileChanger(Thread):
     def __init__(self, sourcefilename, rowfunc, tgpath):
         Thread.__init__(self)
         self.rowfunc = rowfunc
         self.sfname = sourcefilename
         self.tgpath = tgpath

     def run(self):
         tgf = open(join(self.tgpath, basename(self.sfname)), 'w')
         for r in open(self.sfname):
             tgf.write(self.rowfunc(r))
         tgf.close()

# main #
workers = [FileChanger(f, str.upper, '/tmp/tg') \
                for f in listdir('.') if isfile(f)]
for w in workers:
    w.start()
for w in workers:
    w.join()
于 2013-10-19T21:27:04.700 に答える