python for循環多進程執行應用

   以前瞭解過JAVA多線程多進程,python也學到過,但是就沒有遇到過具體的業務場景,最近要做一個文本匹配的任務,需要對70W條文本數據進行推薦相似度的計算,需要做一個全遍歷——也就是一個70W個元素的list遍歷的時候,和自身做一些相關的計算。list中的每個元素沒768維的向量,然後得出結果後,還需要排序,然後寫入文件存儲。這個場景就非常耗時,爲了減少消耗時間,在單機的環境下,就想到了並行。

python的多線程是假的多線程——由於GUI的原因,反正巴拉巴拉。。。就想着用 multiprocessing,這裏採用了簡單的Pool。開始直接上代碼:

datas=[]
for i in range(0,700000):
    a = np.random.random((2,))
    datas.append(a)


p=multiprocessing.Pool(4)
param=[]
    for ele in tqdm(datas,desc='param:'):
        t=(ele,datas)
        param.append(t)
    print('*'*10)
b = p.map(doSomething, param)

def doSomething(a,d):
    # t1 = time.time()
    # r=cdist([a],datas,"cosine")[0]#計算70W次cos值
    # t2 = time.time()
    # print('t2-t1:%4f' % (t2 - t1))
    r=0
    time.sleep(0.0001)
    return r

把上面的70W次的for循環改寫成下面的多進程,運行直接報錯。錯誤在於pool.map(A,B)中的A是函數,B是函數的傳入參數,這個B只能是單個的。爲何我這裏錯了呢?這裏param是單個的呀!然而doSomething()函數有2個參數,代碼本身就有問題。改寫下面2種方式:

def do(param):
    return doSomething(param[0],param[1])

def doSomething(param):
    t1 = time.time()
    r=cdist([param[0]],param[1],"cosine")[0]#計算70W次cos值
    t2 = time.time()
    print('t2-t1:%4f' % (t2 - t1))
    r=0
    time.sleep(0.0001)
    return r

一種是函數嵌套,另一種是直接在doSomething()函數直接實現相應功能。

這裏最重要的一點就是加入要傳入多個參數的話,就必須把多個參數進行封裝,封裝成dic、tuple都行。然後再在函數裏面想辦法使用這些封裝的參數來實現功能。

最後看看耗時對比效果,這裏爲了能夠展示出效果,把裏面的計算cos的功能屏蔽掉,使用sleep()來代替——不代替的話,我這個機子要跑幾百個小時。

完整代碼:

'''
@Author  :    HY
@Software:   PyCharm
@File    :   mutilprocess.py
@Time    :   2019/9/18 23:45
@Desc    :

'''
import time
import multiprocessing
from tqdm import tqdm
from scipy.spatial.distance import cdist
import numpy as np

def doSomething(a,d):
    # t1 = time.time()
    # r=cdist([a],datas,"cosine")[0]#計算70W次cos值
    # t2 = time.time()
    # print('t2-t1:%4f' % (t2 - t1))
    r=0
    time.sleep(0.0001)
    return r
def do(param):
    return doSomething(param[0],param[1])
if __name__ == '__main__':
    datas=[]
    for i in range(0,700000):
        a = np.random.random((2,))
        datas.append(a)
    t1=time.time()
    for e in tqdm(datas):
        doSomething(e,datas)
    t2=time.time()
    print('t2-t1:%4f'%(t2-t1))
    param=[]
    for ele in tqdm(datas,desc='param:'):
        t=(ele,datas)
        param.append(t)
    print('*'*10)

    p=multiprocessing.Pool(4)
    b = p.map(doSomething, param)


    t1 = time.time()
    b=p.map(do,param)
    p.close()
    p.join()
    t2 = time.time()
    print('t2-t1:%4f' % (t2 - t1))

結果:

單核CPU上需要12559秒,4核CPU上只需要362秒。效果很明顯!

 

參考:https://blog.csdn.net/qq_23869697/article/details/84975774

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章