Чтение файла txt с многопоточным в python

Я пытаюсь прочитать файл в python (сканировать его строки и искать термины) и записывать результаты - пусть скажем, счетчики для каждого термина. Мне нужно сделать это для большого количества файлов (более 3000). Можно ли сделать многопоточную? Если да, то как?

Итак, сценарий выглядит так:

  • Прочитайте каждый файл и сканируйте его строки
  • Напишите счетчики в один выходной файл для всех файлов, которые я прочитал.

Второй вопрос: улучшает ли скорость чтения/записи.

Надеюсь, что это достаточно ясно. Спасибо,

Рон.

Ответы

Ответ 1

Я согласен с @aix, multiprocessing, безусловно, путь. Независимо от того, что вы будете связаны с i/o, вы можете читать только так быстро, независимо от того, сколько параллельных процессов вы используете. Но легко может быть некоторое ускорение.

Рассмотрим следующее (input/является каталогом, который содержит несколько файлов .txt из Project Gutenberg).

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

Когда я запускаю это на своей двухъядерной машине, есть заметное (но не 2x) ускорение:

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

Если файлы достаточно малы, чтобы вписаться в память, и у вас много обработки, которая не будет связана с i/o, тогда вы должны увидеть еще лучшее улучшение.

Ответ 2

Да, это должно быть возможно сделать это параллельно.

Однако в Python трудно достичь parallelism с несколькими потоками. По этой причине multiprocessing является лучшим выбором по умолчанию для параллельных действий.

Трудно сказать, какого ускорения вы можете ожидать. Это зависит от того, какую часть рабочей нагрузки можно будет делать параллельно (чем лучше, тем лучше), и какую часть придется делать серийно (чем меньше, тем лучше).