Gáb*_*dős 6 python 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]
Run Code Online (Sandbox Code Playgroud)
但是,这个解决方案需要花费相同的时间,就像我只是迭代peptide_kd.keys()并DataFrames逐一填充一样.为什么会这样?有没有办法并行填写所需的dicts并实际上提高速度?我在48核HPC上运行它.
在(1)启动每个进程,以及(2)必须pandas.DataFrame在多个进程中复制(和等)时,会产生大量开销.如果你只需要dict并行填充,我建议使用共享内存dict.如果没有密钥被覆盖,那么这很简单,你不必担心锁.
(注意我在multiprocess下面使用,这是一个分支multiprocessing- 但只有我可以从解释器演示,否则,你必须从下面做__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}
Run Code Online (Sandbox Code Playgroud)
此解决方案不会dict跨进程共享要共享的副本,因此可以减少部分开销.对于像a这样的大型物体pandas.DataFrame,与简单操作的成本相比,它可能很重要x**2.类似地,产生a Process可能需要一些时间,并且您可以通过使用线程(即multiprocess.dummy代替multiprocess您最初发布的解决方案或我的上面的代码)来更快地(对于轻量级对象)执行上述操作.
如果您确实需要共享DataFrames(正如您的代码建议而不是问题所示),您可以通过创建共享内存来实现numpy.ndarray.