2015-03-21 3 views
1

Я пытаюсь получить дескриптор параллелизма python. Это код, я используюПараллелизм Скорость

import time 
from concurrent.futures import ProcessPoolExecutor 

def listmaker(): 
    for i in xrange(10000000): 
     pass 

#Without duo core 

start = time.time() 
listmaker() 
end = time.time() 
nocore = "Total time, no core, %.3f" % (end- start) 


#with duo core 
start = time.time() 
pool = ProcessPoolExecutor(max_workers=2) #I have two cores 
results = list(pool.map(listmaker())) 
end = time.time() 
core = "Total time core, %.3f" % (end- start) 

print nocore 
print core 

Я был в предположении, что, поскольку я использую два ядра моя скорость будет близка к двойной. Однако, когда я запускаю этот код большую часть времени, выход nocore работает быстрее, чем выход core. Это верно, даже если я изменю

def listmaker(): 
     for i in xrange(10000000): 
      pass 

в

def listmaker(): 
     for i in xrange(10000000): 
      print i 

На самом деле в некоторых запусках no core бежать быстрее. Может ли кто-то пролить свет на этот вопрос? Я правильно настроен? Я делаю что-то неправильно?

+1

'pool.map (listmaker())' вызывает функцию 'listmaker' сразу (в основном процессе) и передает возвращаемое значение (' None') в 'pool.map'. Вам нужно передать функцию 'listmaker' (без круглых скобок) и итерабельность аргументов в' pool.map'. – Blckknght

+0

Это WORKED !, я не понимал, что я назвал эту функцию подобной, если вы ответите на нее плохо. – reticentroot

ответ

1

Вы используете pool.map() неправильно. Взгляните на документацию pool.map. Он ожидает итеративный аргумент, и он будет передавать каждый из элементов из итерабельного в пул отдельно. Так как ваша функция возвращает None, ей ничего не остается. Тем не менее, вы по-прежнему несете накладные расходы на создание новых процессов, что требует времени.

Ваше использование pool.map должно выглядеть следующим образом:

results = pool.map(function_name, some_iterable) 

Обратите внимание несколько вещей:

  • Поскольку вы используете оператор печати, а не функцию, я предполагаю, что ты используя один вариант Python2. В Python2 pool.map возвращает список в любом случае. Не нужно снова преобразовывать его в список.
  • Первым аргументом должно быть имя функции без круглых скобок. Это определяет функцию, которую должны выполнять работники пула. Когда вы включаете круглые скобки, функция вызывается прямо там, а не в пуле.
  • pool.map предназначен для вызова функции для каждого элемента в итерабельном виде, поэтому ваши тестовые примеры должны создавать для него итерацию, а не функцию, которая не принимает никаких аргументов, подобных вашему текущему примеру.

Попробуйте снова запустить пробную версию с некоторым фактическим входом в функцию и получить выход. Вот пример:

import time 
from concurrent.futures import ProcessPoolExecutor 

def read_a_file(file_name): 
    with open(file_name) as fi: 
     text = fi.read() 
    return text 

file_list = ['t1.txt', 't2.txt', 't3.txt'] 

#Without duo core 
start = time.time() 
single_process_text_list = [] 
for file_name in file_list: 
    single_process_text_list.append(read_a_file(file_name)) 
end = time.time() 
nocore = "Total time, no core, %.3f" % (end- start) 


#with duo core 
start = time.time() 
pool = ProcessPoolExecutor(max_workers=2) #I have two cores 
multiprocess_text_list = pool.map(read_a_file, file_list) 
end = time.time() 
core = "Total time core, %.3f" % (end- start) 

print(nocore) 
print(core) 

Результаты:

Общее время, без сердечника, 0,047
Общее время, отводимое, 0,009

Текстовые файлы 150000 строк бредом каждого. Обратите внимание, как много работы нужно было выполнить до того, как параллельная обработка стоила того. Когда я запускал пробную версию с 10 000 строк в каждом файле, один процесс был еще быстрее, потому что у него не было накладных расходов на создание дополнительных процессов. Но с такой большой работой, дополнительные процессы становятся стоить усилий.

И, кстати, эта функция доступна с multiprocessing pools в Python2, поэтому вы можете избежать импорта чего-либо из фьючерсов, если хотите.

+0

Спасибо за информацию. – reticentroot

+0

@hrand Я разместил код примера, который может вам пригодиться. – skrrgwasme

+0

Это замечательно! благодаря – reticentroot

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