Sort.py
import random
import time
def time_analysis(func):
def do_func(*args, **kwargs):
print('[INFO] \'{}\' analysis started (N = {}).'.format(func.__name__, len(args[0])))
start_time = time.clock()
result = func(*args, **kwargs)
end_time = time.clock()
total_time = end_time - start_time
print('[INFO] \'{}\' took {} seconds (N = {}).'.format(func.__name__, total_time, len(args[0])))
return result
return do_func
@time_analysis
def bubble_sort(num_list):
num_len = len(num_list)
for i in range(num_len - 1):
for j in range(num_len - i - 1):
if num_list[j] > num_list[j + 1]:
num_list[j], num_list[j + 1] = num_list[j + 1], num_list[j]
return num_list
if __name__ == '__main__':
N = 30000
random_list = list(range(N))
random.shuffle(random_list)
bubble_sort(random_list)
random_list = list(range(N))
random.shuffle(random_list)
bubble_sort(random_list)
Parallel.py
from multiprocessing import Pool, cpu_count
from Sort import *
def bubble_sort_parallel(*args, **kwargs):
return bubble_sort(*args, **kwargs)
if __name__ == '__main__':
N = 30000
random_list = list(range(N))
random.shuffle(random_list)
pool.apply_async(bubble_sort_parallel, (random_list,))
random_list = list(range(N))
random.shuffle(random_list)
pool.apply_async(bubble_sort_parallel, (random_list,))
pool.close()
pool.join()
Один поток занял всего 2 секунды, а многопроцессорность - 8 секунд.
N = 300 000. Одиночный поток занял всего 200 секунд, а многопроцессорность - 1400 секунд.
Почему использование многопроцессорной обработки медленнее, чем однопоточная?
Как я мог улучшить производительность?
Платформа: Linux, pypy2.7-5.10.0, 4 ядра на моем компьютере
Многопроцессорность: [Рисунок многопроцессорности] [https://i.stack.imgur.com/QksXf.png]
Одиночный поток: [Рисунок одного потока] [https://i.stack.imgur.com/9HYw7.png]
Вы также учли тот факт, что массивы, которые вы передаете в многопроцессорную версию, отличаются от обычной версии? Это может повлиять на производительность. Кроме того, сколько ядер у вас на машине?
Я заметил, что random.shuffle возвращает None, поэтому это может повлиять на вашу среду выполнения: вы фактически не передаете список своим функциям сортировки.
Я предполагаю, что вы используете BubbleSort исключительно для того, чтобы что-то запустить, экспериментируя с многопроцессорностью. Для фактических целей сортировки BubbleSort полезен только для демонстрации своей неполноценности почти всем другим (нормальным) алгоритмам сортировки. ;)
Извините, я ввел неправильный код. Я поправил.
BubbleSort - это не производительность, но почему многопроцессорность медленнее, чем однопоточная?
Если вы увеличите размер списка до 300 000, останется ли разница между параллельным и последовательным выполнением?
Я пробовал 300 тысяч. Параллельный процесс занял 1400 секунд, а последовательный инструмент - всего 200 секунд.






Я пробовал с N=15000. На моем компьютере он работал почти одинаково, то есть непараллельная версия отсортировала один массив за 26 секунд. и параллельная версия отсортировала два массива за 28 секунд. Ставил pool = Pool(2). Вы пытались увеличить N, возможно, ваши результаты будут сопоставимы для больших значений N в вашей среде.
p.s. Вы также должны иметь в виду, что для создания процессов также требуются ресурсы и используются некоторые инструменты синхронизации.
Я надеюсь, что это уже было вам ясно: Pool.apply_async позволяет вам передавать работу другим процессам в пуле; он не выполняет автоматическое распараллеливание отдельной функции. Другими словами, обе версии выполняют каждую сортировку в одном потоке на одном ядре. Параллельная версия должна отправлять два вызова сортировки на два ядра, но вы измеряете время выполнения каждой сортировки, а не выполнение всей программы, поэтому вы не обнаружите какой-либо экономии из-за перекрытия двух вызовов сортировки. (Кроме того, в настоящее время ваш код не включает создание объекта пула, поэтому я просто предполагая, который вы использовали processes=N для N> 2 - хотя, опять же, это не имеет значения, поскольку вы не измеряете общий время выполнения, а скорее время выполнения каждого вида.)
(Если нет, см. https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers а также https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.pool)
Это, однако, не объясняет, почему просто отправка работы другому процессу приводит к более медленному времени выполнения. (Стоит отметить, что на моем MacBook Pro нет разницы во времени выполнения между простой версией и «параллельной» версией.) Причина медленности - связь между процессами. Вы просите его передать большой список через свой канал IPC, и он явно неэффективен при этом. Вы можете продемонстрировать это сами: переместите создание и перемешивание списка в bubble_sort_parallel и сделайте аргумент для предоставленной функции в pool.apply_async пустым списком. На моем компьютере это делает среду выполнения идентичной базовой версии.
Когда я запускаю
Sort.pyсамостоятельно, я получаюTypeError: object of type 'NoneType' has no len(). Это предназначено? Как вы оцениваете сроки однопоточного подхода?