我在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 dists
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.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
在我的电脑中,它消耗了大约118秒,但线程消耗了大约36秒,哪里出了问题?
几个问题:
-
将花费大量时间串行化数据,以便将其发送到其他进程,而线程共享相同的地址空间,以便可以使用指针
-
您当前的代码只使用一个进程来执行多处理的所有计算。你需要以某种方式将你的数组分成"块",这样它就可以通过多个工作进行处理
例如:
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)
这依赖于CCD_ 1是全局变量。对我来说,使用多个进程的版本大约需要5.3秒,而第二个版本大约需要16.9秒。不是数据来回发送速度的4倍,但相当好
我在Python中使用具有大量数据的CSVS时,也有类似的线程和多处理经验。我对此做了一个小的研究,发现处理会产生多个进程来执行任务,这可能比只运行一个线程进程要慢,因为线程在一个地方运行。这里有一个更明确的答案:多处理器与线程Python。
从链接粘贴答案,以防链接消失;
线程模块使用threads
,多处理模块使用processes
。不同之处在于,线程在相同的内存空间中运行,而进程具有单独的内存。这使得在具有多处理的进程之间共享对象变得有点困难。由于线程使用相同的内存,因此必须采取预防措施,否则两个线程将同时写入同一内存。这就是全局解释器锁的作用。
生成进程比生成线程慢一点。一旦它们开始运行,就没有太大区别。