一次对多个文本文件中的频率进行计数的多重处理



我有两个文本文件。我想找出它们中一个字母(例如:"L"(的频率。有没有一种方法可以应用ThreadPoolExecutitor或ProcessPoolExecutitor来加快速度?

到目前为止,我已经尝试过了,这只会增加所需的时间。

def countFreq(data):
res = {i : data.count(i) for i in set(data)}
print(res)

这是我正在使用的频率计数函数。我也已将文本文件转换为字符串。

#Normal method    
start = time.time()
countFreq(str1)
countFreq(str2)
end = time.time()
print(f"Time taken: {end-start:.5f} secondsn")

上面的代码比下面的代码快,为什么

#Method multiprocessing
start = time.time()
p1 = multiprocessing.Process(countFreq(str1))
p2 = multiprocessing.Process(countFreq(str2))
p1.start()
p2.start()
p1.join()
p2.join()
end = time.time()
print(f"Time taken: {end-start:.5f} secondsn")

关于如何让他们跑得更快,有什么想法吗?是IO相关问题还是处理相关问题?

使用并行/并发编程不一定会增加程序的加速,有时最好按顺序进行,尤其是如果我们希望这些线程/进程计算文本文件中的每个字母。

创建一个新进程需要大量资源,并且需要使用CPU才能并行运行。与线程相比,生成和管理进程需要大量的计算时间和能力,但即使这样也不能保证。

为了只计算2个文件,我会尝试线程/保持它的顺序。当文件数量变大时,我们基本上会注意到顺序和并行的加速之间的差异。

要了解更多信息,我强烈建议阅读有关Amdahl定律的文章。

附带说明一下,应该将函数地址传递给multiprocessing.Process内的target参数,并将参数传递给args参数。请注意,它的类型应该是Tuple[Any],因此您应该添加一个尾随逗号,如下所示:target=countFreq, args=(str1,)

import time
import multiprocessing

def count_freq(data):
res = {i: data.count(i) for i in set(data)}
print(res)

def text_to_string(path):
with open(path, 'r') as file_handler:
return file_handler.read()

def main():
start = time.time()
count_freq(text_to_string('./text1'))
count_freq(text_to_string('./text2'))
# about 0.001
end = time.time()
print(f'sequential: {end - start} s')
start = time.time()
p1 = multiprocessing.Process(target=count_freq, args=(text_to_string('./text1'),))
p2 = multiprocessing.Process(target=count_freq, args=(text_to_string('./text2'),))
p1.start()
p2.start()
p1.join()
p2.join()
end = time.time()
print(f'concurrent: {end - start} s')

if __name__ == '__main__':
main()

最新更新