首页 > 解决方案 > 通过服务器读取数据时,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 倍。我在每次测试之间重新启动内核,并进行了几次测试以验证结果。

这令人沮丧。我正在寻找加快代码速度的方法。感谢所有想法!

标签: pythonbinaryseek

解决方案


推荐阅读