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)調用添加到平方函數。這模擬了長時間運行的任務。當然,您可能想要縮小列表的大小,否則將需要永久完成。