Python 使用多处理读取文本文件的速度比不使用多处理读取文本文件的速度慢
我有一些文本文件需要用Python阅读。文本文件只保留一个浮点数组(即没有字符串),数组的大小为2000×2000。我尝试使用Python 使用多处理读取文本文件的速度比不使用多处理读取文本文件的速度慢,python,numpy,multiprocessing,Python,Numpy,Multiprocessing,我有一些文本文件需要用Python阅读。文本文件只保留一个浮点数组(即没有字符串),数组的大小为2000×2000。我尝试使用多处理包,但由于某些原因,它现在运行较慢。我在电脑上下载以下代码的时间如下 多线程:73.89秒 单线程:60.47秒 我做错了什么,有没有办法加快这项任务?我的电脑由Intel Core i7处理器驱动,在现实生活中,我有数百个这样的文本文件,600个甚至更多 import numpy as np from multiprocessing.dummy import
多处理
包,但由于某些原因,它现在运行较慢。我在电脑上下载以下代码的时间如下
- 多线程:73.89秒
- 单线程:60.47秒
import numpy as np
from multiprocessing.dummy import Pool as ThreadPool
import os
import time
from datetime import datetime
def read_from_disk(full_path):
print('%s reading %s' % (datetime.now().strftime('%H:%M:%S'), full_path))
out = np.genfromtxt(full_path, delimiter=',')
return out
def make_single_path(n):
return r"./dump/%d.csv" % n
def save_flatfiles(n):
for i in range(n):
temp = np.random.random((2000, 2000))
_path = os.path.join('.', 'dump', str(i)+'.csv')
np.savetxt(_path, temp, delimiter=',')
if __name__ == "__main__":
# make some text files
n = 10
save_flatfiles(n)
# list with the paths to the text files
file_list = [make_single_path(d) for d in range(n)]
pool = ThreadPool(8)
start = time.time()
results = pool.map(read_from_disk, file_list)
pool.close()
pool.join()
print('finished multi thread in %s' % (time.time()-start))
start = time.time()
for d in file_list:
out = read_from_disk(d)
print('finished single thread in %s' % (time.time() - start))
print('Done')
您使用的是
多处理.dummy
,它复制了多处理的API,但实际上它是线程模块的包装器。
因此,基本上您使用的是线程
,而不是进程
。当您想要执行计算任务时,python中的线程
是没有用处的(由于GIL)
因此,请替换:
from multiprocessing.dummy import Pool as ThreadPool
与:
from multiprocessing import Pool
我已经试着在我的机器上运行你的代码,它有一个i5处理器
,它在45秒内完成了执行。所以我想说这是一个很大的进步
希望这能澄清您的理解。您似乎只测试了10个文件。请注意,多处理有一些重要的启动时间。如果您有100或1000个文件,会发生什么情况?使用多处理总是包括以下方面的开销:spawnig线程、等待线程、加入结果等。IO操作的大部分时间,速度较慢的是打开/关闭文件的IO访问。如果使用多线程技术性能更好,则取决于数据/情况-似乎您的情况并非如此(在本测试案例中)。@quamrana,谢谢,刚刚编辑了我的帖子。我有好几百个这样的文件,不仅仅是10或20个,当你用100或1000个文件测试时会发生什么?我的意思是在你发布的测试代码中使用
n=100
或n=1000
。您可以让save_flatfiles()
生成较小的文件进行测试。您确定读取或写入文件是一项计算任务吗?@SergeBallesta不仅仅是读取或写入文件,OP使用numpy实际执行从存储器加载数据的计算任务,然后numpy将该数据映射到ndarray
。你不认为这是计算性的吗?我的意思是,在这种任务中,大部分时间都花在磁盘io上。而且有许多进程竞争磁盘可能会减慢整个操作。向Shubham大声喊叫!非常感谢,你成功了。有了您的更改,我的代码(对于n=10
)运行时间为20.8秒。当我设置n=100
时,没有多处理的时间是594秒,而多处理的时间是197秒used@Aenaon正如@SergeBallesta也提到的,当您的任务更多地依赖于I/O而不是CPU密集型工作时,dummy将是一个更好的选择。因此,您必须根据您的需求对用例进行加权。