我有两个文本文件。我想找出它们中一个字母(例如:"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()