我试图使用多处理模块来加快我的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模块,但未能使其正常工作。
任何帮助将不胜感激。
答案 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)
其背后的原因是:
*表示在调用foo.run_1()时。 主要正在为其自身映射。 很像告诉自己该怎么做。
*当foo_run2()称为 main 时,正在映射该pc的最大进程能力。 如果最大进程为6,则主要映射为6个线程。 就像组织六个人来告诉你一些事情。
侧面说明: 如果您使用:
p.imap(self.compute,self.A_list)
这些项目将按顺序添加到A_list