2015-02-13 3 views
1

Я пытаюсь улучшить производительность скрипта, который анализирует данные из больших текстовых файлов (1-100gb). Я думал, что буду многопроцессорным, чтобы посмотреть, не ускорит ли это. Насколько я могу судить, процессы начинаются нормально, но это примерно в 3 раза медленнее, чем сохранение без многопроцессорности.Выход многопроцессорного файла значительно медленнее

Версия многопроцессорная:

from multiprocessing import Lock, Process 
from datetime import datetime 

def worker(mylist, count): 
    outFile = str(count) + '.txt' 
    out = open(outFile,'w') 
    for i in mylist: 
     out.write(i)   

def main(): 
    ## lock = Lock() 
    startTime = datetime.now() 
    jobs = [] 
    tempList = [] 
    count = 0 
    inFile = open('batch1.kscsv','r') 
    for line in inFile: 
     if('Traversal' in line and len(tempList) == 0): 
      traversalString = line 
     if('Traversal' not in line and 'Spot' not in line and 'XValue' not in line): 
      line = line.replace(',',' ') 
      tempList.append(line) 
     if('Traversal' in line and len(tempList) > 0): 
      spotFromFile = (traversalString.split(',')[1]).strip() 
      count += 1 
      p = Process(target=worker, args=(tempList, count,)) 
      p.start() 
      tempList = [] 
      traversalString = line 

    print ('Run took: ' + str((datetime.now()-startTime))) 


if __name__ == '__main__': 
    main() 

Очередной сценарий:

from datetime import datetime  

def main(): 
    startTime = datetime.now() 
    jobs = [] 
    tempList = [] 
    count = 0 
    inFile = open('batch1.kscsv','r') 
    for line in inFile: 
     if('Traversal' in line and len(tempList) == 0): 
      traversalString = line 
     if('Traversal' not in line and 'Spot' not in line and 'XValue' not in line): 
      line = line.replace(',',' ') 
      tempList.append(line) 
     if('Traversal' in line and len(tempList) > 0): 
      spotFromFile = (traversalString.split(',')[1]).strip() 
      count += 1 

      outFile = str(count) + '.txt' 
      out = open(outFile,'w') 
      for i in tempList: 
       out.write(i) 

      tempList = [] 
      traversalString = line 


    print ('Run took: ' + str((datetime.now()-startTime))) 


if __name__ == '__main__': 
    main() 

Является ли это проблемой, что это просто не очень хорошо подходит для многопроцессорных? Или есть способ улучшить многопроцессорность?

+0

Coud вы загружаете файл 'batch1.kscsv' где-нибудь, чтобы я мог проверить его на своей машине. – laike9m

+0

@ laike9m Файл в основном повторение ху координат, как: Traversal Index, 256 XValue: Дальтон, YValue 2998.18398466268,0.01116455 2998.43673408455,0.01067383 2998.68949776728,0.01160645 2998.94227571129,0.01089355 2999.19506791702,0.01139648 2999.44787438491,0.01166748 2999.70069511539, 0.01152344 2999.95353010889,0.0110791 – user2267354

ответ

0

Использование нескольких процессов поможет вам с задачами, связанными с ЦП. В этом случае функция, которую вы делегируете, просто открывает файл и записывает на него. Вероятно, это будет главным образом привязано к IO, и вы просто имеете больше процессов в конфликте для дисковых ресурсов.

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

def worker(mylist, count): 
    outFile = str(count) + '.txt' # a few variable and string operations, CPU, fast 
    out = open(outFile,'w') # system call, won't benefit from multiprocessing much, slow 
    for i in mylist: # increment a counter, CPU, fast 
     out.write(i) # write to file, IO, slow 

И здесь:

# forking, fixed cost, expensive, adds work for the kernel in tracking COW or consumes lots of memory depending on OS. 
p = Process(target=worker, args=(tempList, count,)) 
p.start() 

Multiprocessing начнет быть полезным, если функция работник фактически должен сделать много работы на входе. Поиски деревьев, вычисления и т. Д. Еще раз, было бы полезно иметь фиксированное количество процессов, работающих от очереди, а не создавать новый процесс для каждого анализа (если их мало).

+0

Спасибо за ответ. Таким образом, задача просто не подходит для многопроцессорности, поскольку она не требует интенсивного использования ЦП. – user2267354

+0

Это в основном это. IO и три 'if ... in ...', вероятно, являются наиболее трудоемкими, и они выходят за рамки многопроцессорности. Для сканирования миллионов строк, используя else, если вместо поиска строк и начиная с наиболее вероятного случая, возможно, вы можете немного сэкономить. –

Смежные вопросы