并行化对字典的修改

时间:2017-04-07 19:53:31

标签: python dictionary parallel-processing

我有一个包含列表的字典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)

2 个答案:

答案 0 :(得分: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)

答案 1 :(得分:0)

由于GIL,Python不擅长 CPU绑定多线程。如果要加速CPU绑定计算,请使用multiprocessing

我会将字典中的键分成尽可能多的列表。然后我将这些列表与原始字典或其相关部分一起传递给子进程(如果值是大对象图)。

子进程将返回部分结果,主进程将合并为单个结果。

对于 I / O绑定的计算,相同的方法可以使用threading,这可能更快,因为数据将直接在线程之间共享。

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