欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

python多进程逐对比较文档相似度+均分比较次数

程序员文章站 2022-05-02 13:19:13
...

多进程提高运算效率

最近用python做数据处理,363个文件逐对比较相似度,总共65703次。之前学习神经网络发现cpu使用率只有30%多,应该是只用了一核,这次计算密集型任务,用多进程跑下看看提速效果。先把分析对象拆成多份,让每份的数量基本均匀,然后多线程跑,风扇果然嗡嗡起来了。下面是一个小样本量的测试结果,由于每次比对的计算量不同,所以效率不会是线性提升,我做了一个计算量相同的测试,效率也不是线性提升的,不是简单的多用一核就能提高一倍效率,这个好理解。总cpu使用率相对每个cpu使用率是线性累加的。我的cpu是i7-7500U CPU @ 2.70GHz~2.90G,双核双线程四个逻辑核。三个线程基本就跑满了。对于大数据量的场景,多线程的威力就发挥得更明显了。

我有一次跑的过程中报错了,没细看,里面有pandas的内容,直觉是多进程可能不稳定,后面再跑没遇到过。

运行环境 进程数 总cpu使用率 每进程cpu使用率 耗时(s)
ubuntu子系统 1 37% 32 94
ubuntu子系统 2 65% 31 67
ubuntu子系统 3 96% 30 60
ubuntu子系统 4 100% 24 57

细致比较多进程

364个文件逐对比较,总共比较次数为66066

进程 起始时间戳 处理条数 耗时(s)
1个进程 - - -
进程1 1528290177.8083532 66066 19.36804223060608
66066 19.423198461532593
2个进程 - - -
进程1 1528290066.5728095 33153 10.518495559692383
进程2 1528290066.5882878 32913 10.646009922027588
66066 10.698017120361328
3个进程 - - -
进程1 1528289094.8444376 22011 9.382812976837158
进程2 1528289094.8605711 22110 9.47968602180481
进程3 1528289094.8762245 21945 9.627197742462158
66066 9.712886095046997
4个进程 - - -
进程1 1528289148.3423731 16302 9.519663095474243
进程2 1528289148.3572035 16611 9.670548915863037
进程3 1528289148.376095 16471 9.6192147731781
进程4 1528289148.3954604 16682 9.710239171981812
66066 9.799142360687256

结论:1个进程到2个进程接近线性提升,3个进程提升微弱,4个进程反而比3个进程更慢。

多进程代码

if __name__ == '__main__':

    start = time.time()

    # 进程安全的列表
    result = Manager().list()

    # 下面均分函数的输出
    shred = [(0, 49), (49, 106), (106, 182), (182, 364)]

    # 将进程添加进列表
    task = []

    for i in shred:
        task.append(Process(target=compare, args=(i[0], i[1], result)))

    # 逐个启动进程,不要把join直接写在start后面,那样就成单进程了
    for i in task:
        i.start()

    # 进程全部阻塞以后再打印列表    
    for i in task:
        i.join()

    for i in result:
        print(i)

    print(time.time() - start)

均分比较次数

n个文件逐对比较总共比较len(list(itertools.combinations(range(100),2)))次,写了一个均分比较次数的函数,比较弱,但还好使。我觉得这可以作为一道面试题。

"""
"""
均分比较次数
输入:file-文件数量 shred-份数
输出:列表,元素是分段起止位置组成的元祖
"""
def find_div_pos(file, shred):
    s = sum(range(file))
    point = [s * i / shred for i in range(1, shred + 1)][:-1]
    result = []
    for p in point:
        accu = file - 1
        # 倒着迭代是为了更快找到切分点
        # 每次都从头开始迭代影响效率,但是可以忽略
        for i in range(file - 2, 0, -1):
            accu += i
            if abs(accu - i - p) > abs(accu - p) < abs(accu + i - 1 - p):
                result.append(file - i)
                break
    return list(zip([0] + result, result + [file]))


re = find_div_pos(364, 4)
相关标签: 多进程