繁体   English   中英

Python 3 Multiprocessing Pool在使用大变量时速度较慢

[英]Python 3 Multiprocessing Pool is slow with large variables

在Python 3中使用多处理池时,我遇到了一个非常特殊的问题。请参见下面的代码:

import multiprocessing as MP                                       

class c(object):                                                   
    def __init__(self):                                            
        self.foo = ""                                              

    def a(self, b):                                                
        return b                                                   

    def main(self):                                                
        with open("/path/to/2million/lines/file", "r") as f:
            self.foo = f.readlines()                               

o = c()                                                            
o.main()                                                           
p = MP.Pool(5)                                                     
for r in p.imap(o.a, range(1,10)):                                 
    print(r)                                                       

如果按原样执行此代码,这将是极其缓慢的结果:

1
2
3
4
5
6
7
8
9

real    0m6.641s
user    0m7.256s
sys     0m1.824s                    

但是,如果我删除了o.main() ,那么执行时间会快得多:

1
2
3
4
5
6
7
8
9

real    0m0.155s
user    0m0.048s
sys     0m0.004s

我的环境具有强大的功能,并且确保未遇到任何内存限制。 我还用一个较小的文件进行了测试,执行时间更可接受。 有见识吗?

编辑:我删除了磁盘IO部分,而只是创建了一个列表。 我可以证明磁盘IO与该问题无关...

for i in range(1,500000):
    self.foo.append("foobar%d\n"%i)

real    0m1.763s user    0m1.944s sys     0m0.452s

for i in range(1,1000000):
    self.foo.append("foobar%d\n"%i)
real    0m3.808s user    0m4.064s sys     0m1.016s

在后台, multiprocessing.Pool使用Pipe将数据从父进程传输到Pool工作器。

由于整个o对象被序列化为Pickle对象并通过OS管道进行传输,因此这增加了任务调度的隐性成本。

这是针对您计划的每个任务完成的(在您的示例中为10次)。 如果您的文件大小为10 Mb,则您正在转移100Mb的数据。

根据《 多处理程序设计指南》

应当尽可能避免在进程之间转移大量数据。

加快逻辑速度的一种简单方法是计算文件中的行数,将它们分成相等的块,仅将行索引发送给工作进程,然后让它们open文件, seek正确的行并处理数据。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM