为什么多进程池比for循环慢?

发布于 2021-01-29 16:55:17

from multiprocessing import Pool

def op1(data):
    return [data[elem] + 1 for elem in range(len(data))]
data = [[elem for elem in range(20)] for elem in range(500000)]

import time

start_time = time.time()
re = []
for data_ in data:
    re.append(op1(data_))

print('--- %s seconds ---' % (time.time() - start_time))

start_time = time.time()
pool = Pool(processes=4)
data = pool.map(op1, data)

print('--- %s seconds ---' % (time.time() - start_time))

与pool相比,使用pool的运行时间要慢得多。但是,池不应该使用4个处理器并行进行计算吗?

关注者
0
被浏览
45
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    简短的回答: 是的 ,操作通常将在可用核心(的一部分)上完成。但是 通信开销很大在您的示例中,工作量与开销相比太小

    如果您构建一个池,那么将构造许多 工人 。如果然后指示给map定输入。发生以下情况:

    1. 数据将被 分割 :每个工人获得大约公平的份额;
    2. 数据将 传达 给工人;
    3. 每个工人都要 处理他们 的工作;
    4. 结果被 传达回过程 ; 和
    5. 主要过程 将结果分组在一起

    现在,拆分,通信和联接数据是由主流程执行的所有流程。这些 不能并行化* 。由于操作速度快(输入大小为 n的 O(n) ),因此开销的
    时间复杂度相同 。 __
    *

    如此复杂,即使您拥有数百万个内核,也不会有太大区别,因为传送列表可能已经比计算结果昂贵。

    这就是为什么您应该并行执行 计算量大的任务 。没有简单的任务。处理量应该是 大的 相比通信量。

    在您的示例中,这项工作是 微不足道的 :您将1加到所有元素上。但是,序列化并不是那么简单:您必须对发送给工作人员的列表进行编码。



知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看