簡體   English   中英

Python多處理性能不佳

[英]Poor Python Multiprocessing Performance

我試圖使用多處理模塊加快我的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模塊,但無法使其正常工作。

任何幫助將不勝感激。

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

是的,這是因為工作人員必須同時訪問對象,這很昂貴。

所以我玩了一點,通過使計算方法靜態化,設法獲得了很多性能。 因此,基本上,您不再需要共享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. 地圖通話是由main執行

*表示在調用foo.run_1()時。 主要是為自己映射。 很像告訴自己該怎么做。

*調用foo_run2()時, 主要是映射該pc的最大進程功能。 如果最大進程為6,則主要是6個線程的映射。 很像組織六個人來告訴你一些事情。

旁注:如果您使用:

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

這些項目將附加到A_list

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM