2017-04-07 82 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,因为数据会在线程之间共享直接可能更快。

以上是非常通用的。我不知道如何最好地分配您的密钥空间,以实现均匀加载和最大加速;你必须做实验。