多处理一次计算多个文本文件中的频率
Multiprocessing to count frequency in multiple text files at once
我有 2 个文本文件。我想在他们两个中找到一个字母(例如:“L”)的频率。有没有办法应用 ThreadPoolExecutor 或 ProcessPoolExecutor 来加快速度?
到目前为止我试过它只会增加花费的时间。
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} seconds\n")
上面的代码比下面的代码快,这是为什么
#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} seconds\n")
关于如何运行它们更快的任何想法?是IO相关还是处理相关的问题?
使用 parallel/concurrent 编程不一定会提高程序的 速度 ,有时最好按顺序保持它,特别是如果我们期望从这些 threads/processes 要做的是计算文本文件中的每个字母。
创建一个新进程需要大量资源并使用您的 CPU(s) 以便 运行 它们并行。与使用线程执行相同操作相比,生成和管理进程需要大量的计算时间和能力,但即使这样也不能保证。
为了仅计算 2 个文件,我会尝试 threads/keep 按顺序进行。当文件数量变大时,我们基本上会注意到顺序和并行加速之间的差异。
有关更多信息,我强烈建议阅读有关 Amdahl's law 的内容。
作为旁注,您应该将函数地址传递给 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()
我有 2 个文本文件。我想在他们两个中找到一个字母(例如:“L”)的频率。有没有办法应用 ThreadPoolExecutor 或 ProcessPoolExecutor 来加快速度?
到目前为止我试过它只会增加花费的时间。
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} seconds\n")
上面的代码比下面的代码快,这是为什么
#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} seconds\n")
关于如何运行它们更快的任何想法?是IO相关还是处理相关的问题?
使用 parallel/concurrent 编程不一定会提高程序的 速度 ,有时最好按顺序保持它,特别是如果我们期望从这些 threads/processes 要做的是计算文本文件中的每个字母。
创建一个新进程需要大量资源并使用您的 CPU(s) 以便 运行 它们并行。与使用线程执行相同操作相比,生成和管理进程需要大量的计算时间和能力,但即使这样也不能保证。
为了仅计算 2 个文件,我会尝试 threads/keep 按顺序进行。当文件数量变大时,我们基本上会注意到顺序和并行加速之间的差异。
有关更多信息,我强烈建议阅读有关 Amdahl's law 的内容。
作为旁注,您应该将函数地址传递给 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()