python - 通过服务器读取数据时,python f.read() 和 f.seek() 很慢
问题描述
我有一个函数可以读取存储在远程服务器上的文件的二进制数据。第一次在给定文件上运行它非常慢,而下次我读取同一个文件时却足够快。
这对我来说是个谜,因为文件是在子函数中打开和关闭的(因此性能应该是一致的,而不取决于我之前是否阅读过该特定文件)。
数据存储在〜300mb的二进制文件中,我需要读取每N个数字。例如,我可以读取第 1 个号码、第 11 个号码、第 21 个号码等等,直到文件结束。这可以描述为包含 ncol x nrow 矩阵的文件,其中第一组 ncol 数字是第 1 行,第二组 ncol 数字是第 2 行等。我想读取一列,即每行一个数字。
我使用 f.seek() 将文件指针设置到文件中的正确位置。
下面的代码第一次运行大约 10 秒,随后运行 0.2 秒。注意,这次只是读取数据,打开文件很快。为什么每次打开和关闭文件时性能会发生变化?
def ReadBinaryFile(文件名,col,ncol):
"""
Args:
filename: binary file with float numbers (4-byte) stored in columns
col: column to read
ncol: number of columns in file (needed to separate data)
Description:
-reads 4-byte numeric data from specified column and converts to float
Returns:
X: list with numeric data
"""
#--------hard-coded variables:
numBytes=4 #4-byte numbers
#---------open file
f = open(filename,'rb') #open file
f.seek(0,2) #put pointer to end of file
nmax = f.tell()/numBytes #total length of data
nrow = nmax/ncol #number of rows
X = [0]*nrow #allocate memory
t0 = time.time() #start timer
for i in xrange(nrow):
f.seek((col-1+i*ncol)*numBytes)
bindata = f.read(numBytes)
X[i] = float(struct.unpack('f',bindata)[0])
t1 = time.time() #end timer
print('Elapsed time reading binary data: ' + str(t1-t0))
f.close()
return X
更新:我重写了循环并将 f.seek() 替换为 f.read() 以在文件中前进。
f.seek((col-1+i*ncol)*numBytes) #set initial file pointer
for i in xrange(nrow):
bindata = f.read(numBytes) #read desired data
X[i] = float(struct.unpack('f',bindata)[0])
f.read(numBytes*(ncol-1)) #move to next row by reading data.
原始代码,用 f.seek() 读取同一个文件两次移动文件指针:第一次读取文件=10.2s,连续读取=0.16s。
更新代码,使用 f.read() 读取同一个文件两次以移动文件指针:
第一次读取文件=1.67s,连续读取=0.25s。
因此,更新后的代码第一次读取文件时速度快了 5 倍,但下次读取速度慢了 2 倍。我在每次测试之间重新启动内核,并进行了几次测试以验证结果。
这令人沮丧。我正在寻找加快代码速度的方法。感谢所有想法!
解决方案
推荐阅读
- javascript - 如果 Wolf 强度 < 1,如何阻止功能关闭
- java - 为什么当我尝试 telnet 时选择方法立即返回 0?
- reactjs - 使用带有 typescript 和 thunk 的 createStore 时出错
- flutter - 在不使用导航器的情况下在小部件之间传递数据?
- ruby-on-rails - RSpec FactoryBot 验证失败的多对多关系
- python - 如何将 python 模块创建为单个可调用函数?
- python - 如何在python中创建表格以按列读取二维数组
- python - 当 data 参数包含 & 时如何发出 HTTP POST 请求?
- c# - Microsoft Identtiy & Identity Server 4 处理流程关系
- java - 为什么我只使用 geofirestore 获得一份文件