python - Python多处理比单处理慢
问题描述
排序.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)
并行.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】
解决方案
我希望您已经清楚这一点: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
在我的计算机上,这使得运行时与基本版本相同。
推荐阅读
- python - ModuleNotFoundError:在 vscode 中没有使用 venv 的模块名为“请求”
- python - 如何根据关键字将python字典解包到变量
- php - 在php中将索引数组转换为二维数组的最佳方法
- python - 导入文件名是灰色的
- python - 如何在 move_dict 中的“say_this”中去掉下划线?
- android - 如何制作自定义对话框
- blazor - Blazor - textarea 绑定到 oninput,但当文本区域的值使用 javascript 更改时不会被调用
- javascript - 如何使用 React Konva Image 将画布重新绘制到自身上?
- r - 如何在 R 中创建关系矩阵?
- php - 对于巨大的表格数据,使用 div 标签是否比使用 table tr 和 td 标签更快?