我编写了一个程序,通过将列表分成子部分并使用Python中的多处理来添加列表,代码如下:
from concurrent.futures import ProcessPoolExecutor, as_completed
import random
import time
def dummyFun(l):
s=0
for i in range(0,len(l)):
s=s+l[i]
return s
def sumaSec(v):
start=time.time()
sT=0
for k in range(0,len(v),10):
vc=v[k:k+10]
print ("vector ",vc)
for item in vc:
sT=sT+item
print ("sequential sum result ",sT)
sT=0
start1=time.time()
print ("sequential version time ",start1-start)
def main():
workers=5
vector=random.sample(range(1,101),100)
print (vector)
sumaSec(vector)
dim=10
sT=0
for k in range(0,len(vector),dim):
vc=vector[k:k+dim]
print (vc)
for item in vc:
sT=sT+item
print ("sub list result ",sT)
sT=0
chunks=(vector[k:k+dim] for k in range(0,len(vector),10))
start=time.time()
with ProcessPoolExecutor(max_workers=workers) as executor:
futures=[executor.submit(dummyFun,chunk) for chunk in chunks]
for future in as_completed(futures):
print (future.result())
start1=time.time()
print (start1-start)
if __name__=="__main__":
main()
问题是,对于顺序版本,我得到的时间为:
0.0009753704071044922
而对于并发版本,我的时间是:
0.10629010200500488
当我把工人的数量减少到2时,我的时间是:
0.08622884750366211
为什么会这样呢?
2条答案
按热度按时间nukf8bse1#
向量的长度只有100。这是一个非常小的工作量,所以启动进程池的固定成本是运行时最重要的部分。因此,当有很多工作要做时,并行是最有益的。尝试一个更大的向量,比如长度为100万。
第二个问题是你让每个工人做的工作量很小:大小为10的块。同样,这意味着启动一项任务的成本不能分摊到这么少的工作中。使用较大的块。例如,使用
10
代替int(len(vector)/(workers*10))
。还要注意,您创建了5个进程。对于像这样的CPU密集型任务,理想情况下,您希望使用与物理CPU内核数量相同的进程。使用系统拥有的任意数量的内核,或者使用
max_workers=None
(默认值),则ProcessPoolExecutor
将默认为您的系统的该数字。如果您使用的进程太少,则会将性能留到桌面上,如果你使用太多,那么CPU将不得不在它们之间切换,你的性能 * 可能 * 会受到影响。esbemjvw2#
你的分块对于创建多个任务来说是相当糟糕的。创建太多的任务仍然会招致时间的惩罚,即使你的工人已经创建好了。
也许这篇文章可以帮助你在你的搜索:How to parallel sum a loop using multiprocessing in Python