0

我想下面的代码:为什么pool.map比普通map慢?

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秒VS14秒)。

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

如果是相关的,这个代码写在Python 2.7,和我的操作系统是Linux Mint的17.2

+0

l有多大? –

+0

@PeterWood:你可以从代码中看到它有'10 ** 8'元素。 – BrenBarn

+0

这是在每个过程中重新创建吗? –

回答

2

pool.map分裂列表为N个就业岗位(其中N是列表的大小),并调度那些过程。

单个进程正在做你的代码中显示的工作:

def square(x): 
    return x**2 

此操作需要很少的时间在现代的CPU,不管数量有多大。

在您的示例中,您正在创建一个巨大的列表并对每个元素执行不相关的操作。当然IPC的开销会比通常的map功能更高,该功能为快速循环而优化。

为了看到您的示例正常工作,只需将一个time.sleep(0.1)调用添加到平方函数。这模拟了长时间运行的任务。当然,您可能想要缩小列表的大小,否则将需要永久完成。