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

评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值