与多处理并行填写字典

时间:2016-07-15 10:01:21

标签: python multiprocess

昨天我问了一个问题:Reading data in parallel with multiprocess

我得到了非常好的答案,我实施了答案中提到的解决方案,我标记为正确。

def read_energies(motif):
    os.chdir("blabla/working_directory")
    complx_ener = pd.DataFrame()
    # complex function to fill that dataframe 
    lig_ener = pd.DataFrame()
    # complex function to fill that dataframe 
    return motif, complx_ener, lig_ener

COMPLEX_ENERGIS = {}
LIGAND_ENERGIES = {}
p = multiprocessing.Pool(processes=CPU)
for x in p.imap_unordered(read_energies, peptide_kd.keys()):
    COMPLEX_ENERGIS[x[0]] = x[1]
    LIGAND_ENERGIES[x[0]] = x[2]

但是,此解决方案需要相同的时间,就像我只是迭代peptide_kd.keys()并逐个填充DataFrames一样。为什么会这样?有没有办法并行填写所需的dicts并实际上提高速度?我在48核HPC上运行它。

1 个答案:

答案 0 :(得分:8)

在(1)启动每个进程,以及(2)必须在多个进程中复制pandas.DataFrame(和等)时,会产生大量开销。如果您只需要并行填充dict,我建议您使用共享内存dict。如果没有密钥被覆盖,那么这很简单,您不必担心锁定。

(注意我正在使用下面的multiprocess,这是multiprocessing的一个分支 - 但只有我可以从解释器演示,否则,你必须从{ {1}})。

__main__

此解决方案不会复制>>> from multiprocess import Process, Manager >>> >>> def f(d, x): ... d[x] = x**2 ... >>> manager = Manager() >>> d = manager.dict() >>> job = [Process(target=f, args=(d, i)) for i in range(5)] >>> _ = [p.start() for p in job] >>> _ = [p.join() for p in job] >>> print d {0: 0, 1: 1, 2: 4, 3: 9, 4: 16} 以跨进程共享,因此可以减少部分开销。对于像dict这样的大型对象,与pandas.DataFrame等简单操作的成本相比,它可能很重要。类似地,生成x**2可能需要一些时间,您可以通过使用线程(即从Process而不是multiprocess.dummy来更快地(对于轻量级对象)执行上述操作最初发布的解决方案或我的上面)。

如果您 需要共享multiprocess(正如您的代码建议而不是问题所示),您可以通过创建共享内存{{1}来实现}。