Читать текстовый файл с многопоточностью в Python - PullRequest
19 голосов
/ 15 октября 2011

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

Итак, сценарий выглядит следующим образом:

  • Чтение каждого файла и сканирование его строк
  • Запись счетчиков в один и тот же выходной файл для всехфайлы, которые я прочитал.

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

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

Рон.

Ответы [ 2 ]

17 голосов
/ 15 октября 2011

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

Обратите внимание на следующее (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

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

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

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

2 голосов
/ 15 октября 2011

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...