我正在学习将池与多处理一起使用。我将此脚本作为练习。
谁能告诉我为什么使用普通的for循环比使用池花费更少的时间?
附言:我的CPU有2个核心。
非常感谢你。
from multiprocessing import Pool
from functools import reduce
import time
def one(n):
a = n*n
return a
if __name__ == '__main__':
l = list(range(1000))
p = Pool()
t = time.time()
pol = p.map(one, l)
result = reduce(lambda x,y: x+y, pol)
print("Using Pool the result is: ", result, "Time: ", time.time() - t )
p.close()
p.join()
def two(n):
t = time.time()
p_result = []
for i in n:
a = i*i
p_result.append(a)
result = reduce(lambda x,y: x+y, p_result)
print("Not using Pool the result is: ", result, "Time: ", time.time() - t)
two(l)
使用池结果为:332833500时间:0.14810872077941895
不使用池结果是:332833500时间:0.0005018711090087891
最佳答案
我认为这里有几个原因,但是我想这很大程度上与运行多个进程的开销有关,这主要与同步和通信有关,以及非并行代码是写得更有效率。
作为基础,这是您未修改的代码在我的计算机上运行的方式:
('Using Pool the result is: ', 332833500, 'Time: ', 0.0009129047393798828)
('Not using Pool the result is: ', 332833500, 'Time: ', 0.000598907470703125)
首先,我想通过使
two()
函数的代码与并行化的代码几乎相同来尝试公平竞争。这是修改后的two()
函数:def two(l):
t = time.time()
p_result = map(one, l)
result = reduce(lambda x,y: x+y, p_result)
print("Not using Pool the result is: ", result, "Time: ", time.time() - t)
现在,在这种情况下,这实际上并没有太大的区别,但是重要的是,在一瞬间,要确保两种情况都在做完全相同的事情。这是此更改的示例输出:
('Using Pool the result is: ', 332833500, 'Time: ', 0.0009338855743408203)
('Not using Pool the result is: ', 332833500, 'Time: ', 0.0006031990051269531)
我现在想说明的是,由于
one()
函数的计算是如此便宜,因此进程间通信的开销超过了并行运行它的好处。我将按以下方式修改one()
函数,以强制它执行大量额外的计算。请注意,由于two()
函数的更改,此更改将同时影响并行代码和单线程代码。def one(n):
for i in range(100000):
a = n*n
return a
for循环的原因是给每个进程一个存在的理由。当您拥有原始代码时,每个进程只需执行几次乘法,然后就必须将结果列表发送回父进程,并等待获得新的块。发送和等待所花费的时间比完成单个块所花费的时间长得多。通过添加这些额外的周期,它迫使每个块花费更长的时间,而无需更改进程间通信所需的时间,因此我们开始看到并行性得到了回报。这是我对
one()
函数进行此更改后运行代码时的结果:('Using Pool the result is: ', 332833500, 'Time: ', 1.861448049545288)
('Not using Pool the result is: ', 332833500, 'Time: ', 3.444211959838867)
所以你有它。您需要做的就是给您的孩子做更多的工作,这将使您更有价值。
关于python-3.x - Python 3多处理池,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/49933088/