为了账号安全,请及时绑定邮箱和手机立即绑定

多处理比python中的线程慢

多处理比python中的线程慢

烙印99 2021-09-14 15:03:09
我在python中测试了一个多进程和线程,但多进程比线程慢,我使用editdistance计算距离,我的代码如下:def calc_dist(kw, trie_word):    dists = []    while len(trie_word) != 0:        w = trie_word.pop()        dist = editdistance.eval(kw, w)        dists.append((w, dist))    return distsif __name__ == "__main__":    word_list = [str(i) for i in range(1, 10000001)]    key_word = '2'    print("calc")    s = time.time()    with Pool(processes=4) as pool:         result = pool.apply_async(calc_dist, (key_word, word_list))         print(len(result.get()))     print("用时",time.time()-s)使用线程:class DistThread(threading.Thread):    def __init__(self, func, args):        super(DistThread, self).__init__()        self.func = func        self.args = args        self.dists = None    def run(self):        self.dists = self.func(*self.args)    def join(self):        super().join(self)        return self.dists在我的电脑中,它消耗了大约118s,但是线程大约需要36s,它是哪里出了问题?
查看完整描述

2 回答

?
慕尼黑的夜晚无繁华

TA贡献1864条经验 获得超6个赞

几个问题:

  1. 将花费大量时间序列化数据,以便将其发送到另一个进程,而线程共享相同的地址空间,因此可以使用指针

  2. 您当前的代码仅使用一个进程来进行多处理的所有计算。你需要以某种方式将你的数组分成“块”,以便它可以通过多个工作人员进行处理

例如:

import time

from multiprocessing import Pool

import editdistance


def calc_one(trie_word):

    return editdistance.eval(key_word, trie_word)


if __name__ == "__main__":

    word_list = [str(i) for i in range(1, 10000001)]

    key_word = '2'


    print("calc")

    s = time.time()

    with Pool(processes=4) as pool: 

        result = pool.map(calc_one, word_list, chunksize=10000) 

        print(len(result))

    print("time",time.time()-s)


    s = time.time()

    result = list(calc_one(w) for w in word_list)

    print(len(result))

    print("time",time.time()-s)

这依赖于key_word作为一个全局变量。对我来说,使用多个进程的版本需要约 5.3 秒,而第二个版本需要约 16.9 秒。还不如来回发送数据快 4 倍,但还不错


查看完整回答
反对 回复 2021-09-14
?
富国沪深

TA贡献1790条经验 获得超9个赞

我在 Python 中使用线程和多处理处理具有大量数据的 CSVS 方面也有类似的经验。我对此进行了深入研究,发现处理会产生多个进程来执行任务,这可能比仅运行一个线程进程要慢,因为线程在一个地方运行。这里有一个更明确的答案:Multiprocessing vs Threading Python

从链接粘贴答案,以防链接消失;

线程模块使用threads,多处理模块使用processes。不同之处在于线程运行在同一个内存空间,而进程有单独的内存。这使得在多处理进程之间共享对象变得有点困难。由于线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁的用途。

生成进程比生成线程慢一点。一旦它们运行起来,就没有太大区别。


查看完整回答
反对 回复 2021-09-14
  • 2 回答
  • 0 关注
  • 164 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信