Python 3 多处理池因变量较大而速度缓慢

f-z*_*f-z 3 python multiprocessing

我在 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)                                                       
Run Code Online (Sandbox Code Playgroud)

如果我按原样执行此代码,这是我非常慢的结果:

1
2
3
4
5
6
7
8
9

real    0m6.641s
user    0m7.256s
sys     0m1.824s                    
Run Code Online (Sandbox Code Playgroud)

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

1
2
3
4
5
6
7
8
9

real    0m0.155s
user    0m0.048s
sys     0m0.004s
Run Code Online (Sandbox Code Playgroud)

我的环境具有充足的功能,并且我已确保不会遇到任何内存限制。我还用较小的文件进行了测试,执行时间更容易接受。有什么见解吗?

编辑:我删除了磁盘 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
Run Code Online (Sandbox Code Playgroud)

nox*_*fox 5

在底层,multiprocessing.Pool使用 aPipe将数据从父进程传输到池工作线程。

o当整个对象被序列化为Pickle对象并通过操作系统管道传输时,这会增加任务调度的隐藏成本。

这是针对您正在安排的每项任务执行的(在您的示例中为 10 次)。如果您的文件大小为 10 Mb,则您将移动 100 Mb 的数据。

根据多处理编程指南

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

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