python 为什么这个多进程程序比它的非并发版本运行得慢?

yzxexxkh  于 2023-02-11  发布在  Python
关注(0)|答案(2)|浏览(105)

我编写了一个程序,通过将列表分成子部分并使用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

为什么会这样呢?

nukf8bse

nukf8bse1#

向量的长度只有100。这是一个非常小的工作量,所以启动进程池的固定成本是运行时最重要的部分。因此,当有很多工作要做时,并行是最有益的。尝试一个更大的向量,比如长度为100万。
第二个问题是你让每个工人做的工作量很小:大小为10的块。同样,这意味着启动一项任务的成本不能分摊到这么少的工作中。使用较大的块。例如,使用10代替int(len(vector)/(workers*10))
还要注意,您创建了5个进程。对于像这样的CPU密集型任务,理想情况下,您希望使用与物理CPU内核数量相同的进程。使用系统拥有的任意数量的内核,或者使用max_workers=None(默认值),则ProcessPoolExecutor将默认为您的系统的该数字。如果您使用的进程太少,则会将性能留到桌面上,如果你使用太多,那么CPU将不得不在它们之间切换,你的性能 * 可能 * 会受到影响。

esbemjvw

esbemjvw2#

你的分块对于创建多个任务来说是相当糟糕的。创建太多的任务仍然会招致时间的惩罚,即使你的工人已经创建好了。
也许这篇文章可以帮助你在你的搜索:How to parallel sum a loop using multiprocessing in Python

相关问题