Python多处理性能不佳

时间:2018-07-19 09:11:35

标签: python python-multiprocessing

我试图使用多处理模块来加快我的python程序的速度,但是我发现它相当慢。 玩具示例如下:

import time
from multiprocessing import Pool, Manager

class A:
    def __init__(self, i):
        self.i = i

    def score(self, x):
        return self.i - x


class B:
    def __init__(self):
        self.i_list = list(range(1000))
        self.A_list = []

    def run_1(self):
        for i in self.i_list:
            self.x = i
            map(self.compute, self.A_list) #map version
            self.A_list.append(A(i))

    def run_2(self):
        p = Pool()
        for i in self.i_list:
            self.x = i
            p.map(self.compute, self.A_list) #multicore version
            self.A_list.append(A(i))

    def compute(self, some_A):
        return some_A.score(self.x)

if __name__ == "__main__":
    st = time.time()
    foo = B()
    foo.run_1()
    print("Map: ", time.time()-st)
    st = time.time()
    foo = B()
    foo.run_2()
    print("MultiCore: ", time.time()-st) 

我的计算机(Windows 10,Python 3.5)的结果是

地图:0.0009996891021728516

多核:19.34994912147522

在Linux Machine(CentOS 7,Python 3.6)上可以观察到相似的结果。

我猜这是由进程间对象的酸洗/描绘引起的?我尝试使用Manager模块,但未能使其正常工作。

任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:1)

哇,令人印象深刻(而且很慢!)。

是的,这是因为工作人员必须同时访问对象,这很昂贵。

所以我玩了一点,通过使计算方法静态化,设法获得了很多性能。因此,基本上,您不再需要共享B对象实例。仍然很慢,但是更好。

import time
from multiprocessing import Pool, Manager

class A:
    def __init__(self, i):
        self.i = i

    def score(self, x):
        return self.i - x

x=0
def static_compute(some_A):
    res= some_A.score(x)
    return res


class B:
    def __init__(self):
        self.i_list = list(range(1000))
        self.A_list = []

    def run_1(self):
        for i in self.i_list:
            x=i
            map(self.compute, self.A_list) #map version
            self.A_list.append(A(i))

    def run_2(self):
        p = Pool(4)
        for i in self.i_list:
            x=i
            p.map(static_compute, self.A_list) #multicore version
            self.A_list.append(A(i))

对我来说,使其变慢的另一个原因是使用Pool的固定成本。您实际上正在启动Pool.map 1000次。如果启动这些流程有固定的成本,那将使整体策略变慢。也许您应该使用更长的A_list(比i_list更长,需要使用其他算法)进行测试。

答案 1 :(得分:0)

其背后的原因是:

  1. 地图通话由主要
  2. 执行

*表示在调用foo.run_1()时。 主要正在为其自身映射。 很像告诉自己该怎么做。

*当foo_run2()称为 main 时,正在映射该pc的最大进程能力。 如果最大进程为6,则主要映射为6个线程。 就像组织六个人来告诉你一些事情。

侧面说明: 如果您使用:

p.imap(self.compute,self.A_list)

这些项目将按顺序添加到A_list