2017-04-07 48 views
0

我有一本字典my_dict包含列表和一個可迭代keys了很多,我想上運行的功能鍵:並行化修改字典

for key in keys: 
    if key in my_dict: 
     my_dict[key].append(my_fun(key, params)) 
    else: 
     my_dict[key] = [my_fun(key, params)]  

my_fun是緩慢的。我該如何平行化這個循環?


難道僅僅是:

import multiprocessing 

def _process_key(key): 
    if key in my_dict: 
     my_dict[key].append(my_fun(key, params)) 
    else: 
     my_dict[key] = [my_fun(key, params)] 

if __name__ == '__main__': 
with Pool(5) as p: 
    p.map(_process_key, keys) 
+0

不,字典需要在父級更新。 – tdelaney

+0

我有點困惑......你用相同的鍵多次調用'my_fun' ...我認爲這是故意的? – tdelaney

回答

2

dict是在母體存儲空間,所以你需要有更新。 pool.map遍歷worker函數返回的任何內容,所以只需將它以有用的形式返回即可。 collections.defaultdict是,爲您創建項目一個幫手,這樣你就可以

import multiprocessing 
import collections 

def _process_key(key): 
    return key, my_fun(key, params) 

if __name__ == '__main__': 
    with Pool(5) as p: 
     my_dict = collections.defaultdict(list) 
     for key, val in p.map(_process_key, keys): 
      my_dict[key].append(val) 
0

Python是不擅長CPU綁定 multithreadng,因爲GIL的。如果您想加速CPU限制的計算,請使用multiprocessing

我會將你的字典的鍵分成儘可能多的列表,因爲你有可用的核心。然後,我會將這些列表與原始字典或其相關部分一起傳遞給子進程(如果值是大對象圖)。

子進程將返回部分結果,主進程將合併成單個結果。

對於I/O綁定計算,同樣的方法將工作使用threading,因爲數據會在線程之間共享直接可能更快。

以上是非常通用的。我不知道如何最好地分配您的密鑰空間,以實現均勻加載和最大加速;你必須做實驗。