为什么pool.map比普通地图慢?

时间:2016-03-07 18:45:35

标签: python performance multiprocessing pool python-multiprocessing

我正在尝试以下代码:

import multiprocessing
import time
import random

def square(x):
    return x**2

pool = multiprocessing.Pool(4)

l = [random.random() for i in xrange(10**8)]

now = time.time()
pool.map(square, l)
print time.time() - now

now = time.time()
map(square, l)
print time.time() - now

并且pool.map版本始终比正常map版本慢了几秒钟(19秒对14秒)。

我已查看过问题:Why is multiprocessing.Pool.map slower than builtin map?multiprocessing.Pool() slower than just using ordinary functions 他们似乎把它归结为IPC开销或磁盘饱和度,但我觉得在我的例子中,这些问题显然不是问题;我没有在磁盘上写入/读取任何内容,并且计算时间足够长,以至于与多处理所节省的总时间相比,IPC开销似乎应该很小(我估计,因为我和#39;我在4个核心而不是1个核心上工作,我应该将计算时间从14秒减少到大约3.5秒。我不会让我的cpu饱和,我不会想到;检查cat /proc/cpuinfo表明我有4个核心,但即使我只处理2个进程,它仍然比正常的映射函数慢(甚至比4个进程慢)。还有什么可能会减慢多处理版本的速度?我误解了IPC开销如何扩展?

如果相关,则此代码用Python 2.7编写,我的操作系统是Linux Mint 17.2

1 个答案:

答案 0 :(得分:2)

pool.map将列表拆分为N个作业(其中N是列表的大小)并将其分配给流程。

单个流程正在进行的工作显示在您的代码中:

def square(x):
    return x**2

此操作在现代CPU上花费的时间非常短,无论数量有多大。

在您的示例中,您创建了一个庞大的列表,并对每个元素执行不相关的操作。当然,与针对快速循环优化的常规map函数相比,IPC开销会更大。

为了让您的示例按预期工作,只需向square函数添加time.sleep(0.1)调用即可。这模拟了一个长期运行的任务。当然,您可能希望减小列表的大小,或者需要永远完成。