Python 3 多处理池速度很慢,变量很大



我在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%dn"%i)
real    0m1.763s user    0m1.944s sys     0m0.452s
for i in range(1,1000000):
self.foo.append("foobar%dn"%i)
real    0m3.808s user    0m4.064s sys     0m1.016s

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

这增加了任务计划的隐性成本,因为整个o对象被序列化为Pickle对象并通过 OS 管道传输。

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

根据多处理编程指南:

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

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

最新更新