2017-01-10 99 views
1

我希望這不是一個重複的問題。運行函數的不同方式之間的性能差異

我已經運行在Python 3.4.2相同功能的簡單的方式,並在多處理方式和我發現,簡單的方法就是更快。也許我的設計不好,但我不知道問題出在哪裏。

下面是我的代碼:

公共部分

import os 
import math 
from multiprocessing import Process 
import timeit 


def exponential(number): 
    """ 
    A function that returns exponential 
    """ 
    result = math.exp(number) 
    proc = os.getpid() 

簡單的解決方案

if __name__ == '__main__': 

    start = timeit.default_timer() 
    numbers = [5, 10, 20, 30, 40, 50, 60] 

    for index, number in enumerate(numbers): 
     exponential(number) 

    stop = timeit.default_timer() 
    duration = stop - start 
    print(duration) 

多處理解決方案

if __name__ == '__main__': 
    start = timeit.default_timer() 
    numbers = [5, 10, 20, 30, 40, 50, 60] 
    procs = [] 

    for index, number in enumerate(numbers): 
     proc = Process(target=exponential, args=(number,)) 
     procs.append(proc) 
     proc.start() 

    for proc in procs: 
     proc.join() 

    stop = timeit.default_timer() 
    duration = stop - start 
    print(duration) 

我看到的是,簡單的解決方案比多處理的速度更快:

Duration with Simple solution:   2.8359994757920504e-05 
Duration with Multi processing solution: 0.012581961986143142 
+5

設置多個進程存在開銷。在這種情況下,簡單的解決方案非常快速,並且切換到多處理以實現如此小的集合大小沒有任何好處。隨着數字長度的增加,這可能會改變。 – nbryans

+0

爲什麼使用'enumerate()'?你永遠不會使用'index'變量,所以你可以直接說'數字中的數字:'。 – reynoldsnlp

+1

謝謝@nbryans –

回答

1

計算math.exp(x),其中x < 100(因爲這是你的情況)並不特別困難。所以你不會並行計算這些並不能提供明顯的優勢。

請記住,當你設置了多個進程,還承擔創建新進程的開銷,並複製了內存空間等

最後,還有什麼可說的對,你創建一個新進程爲該列表中的每個號碼。如果該列表中有100個數字,那麼您將創建100個新進程,這將在您的4個或8個內核上競爭時間(取決於您的CPU),這會增加進一步的延遲(特別是當計算本身變得複雜時)。您最好創建一個流程池,並讓它們逐步處理您的數據集:

import math 
import multiprocess as mp 


def slave(qIn, qOut): 
    for i, num in iter(qIn.get, None): 
     qOut.put((i, math.exp(num)) 
    qOut.put(None) 


def master(): 
    numbers = [5, 10, 20, 30, 40, 50, 60] 

    qIn, qOut = [mp.Queue() for _ in range(2)] 
    procs = [mp.Process(target=slave, args=(qIn, qOut)) for _ in range(mp.cpu_count()-1)] 
    for p in procs: p.start() 
    for t in enumerate(numbers): qIn.put(t) 
    for p in procs: qIn.put(None) 

    answer = [None] * len(numbers) 
    done = 0 
    while done < len(numProcs): 
     t = qOut.get() 
     if t is None: 
      done += 1 
      continue 

     i, e = t 
     answer[i] = e 

    for p in procs: p.terminate() 
    return answer 
相關問題