我必须解析一个巨大的(250MB)文本文件,由于某些原因,它只是一行,导致我尝试的每个文本编辑器(Notepad++、VisualStudio、Matlab)加载失败。因此,我逐段阅读,并在逻辑行(从#
开始)完全读取时解析它:
f = open(filename, "rt")
line = ""
buffer = "blub"
while buffer != "":
buffer = f.read(10000)
i = buffer.find('#')
if i != -1: # end of line found
line += buffer[:i]
ProcessLine(line)
line = buffer[i+1:] # skip the '#'
else: # still reading current line
line += buffer
这是相当好的工作,但是,它可能发生,一行比我的缓冲区短,这将导致我跳过一行。所以我用
while buffer != "":
buffer = f.read(10000)
i = buffer.find('#')
while i != -1:
pixels += 1
line += buffer[:i]
buffer = buffer[i+1:]
ProcessLine(line)
i = buffer.find('#')
line += buffer
,这就成功了。然而,这至少慢了一百倍,使得读取那么大的文件毫无用处。我真的不明白,这怎么可能发生,我确实有一个内部循环,但大多数时候它只重复一次。另外,我可能复制了缓冲区(buffer = buffer[i+1:]
),从中我可以理解性能是否下降了一半,但我不知道这怎么会让它慢100倍。你知道吗
作为旁注:我的(逻辑)行大约是27000字节。因此,如果我的缓冲区是10.000字节,我在第一个实现中从不跳过行,如果是30.000,我就跳过行。但是,这似乎不会影响性能,即使第二个实现中的内部循环最多只评估一次,性能仍然很糟糕。你知道吗
引擎盖下到底发生了什么事,我错过了?你知道吗
您的第二个版本不仅工作较慢,而且工作不正确。你知道吗
在第一个版本中,您用赋值(
line = buffer[i+1:]
)重置line
,而在第二个版本中,您只附加到line
。结果,在第二个版本中,line
包含文件的全部内容,而不是#
符号。你知道吗通过在处理代码后立即清除
line
来修复代码:如果我正确理解了您要做的事情,那么两个版本的代码都是错误的。就像@Leon在第二个版本中说的,你在
ProcessLine(line)
之后缺少了line = ""
,而在第一个版本中,只有第一行是正确的,如果行比buffer短,你只在line += buffer[:i]
中使用了buffer的第一部分,但是问题出在这一行line = buffer[i+1:]
,所以如果你的line
有1000个字符长,而且buffer
是10000个字符长,那么当您使用line += buffer[:i]
时,您的行将是9000个字符长,可能包含多行。从阅读:这样做相当有效,但是,可能会发生这样的情况,即一行比缓冲区短,这会导致我跳过一行
我想你已经意识到了这一点,但我之所以要写得详细,是因为这也是为什么你的第一个版本工作得更快的原因。你知道吗
在解释了这一点之后,我认为最好的方法是读取孔文件,然后拆分文本以获得行,因此您的代码如下所示:
然后你就可以用这样的方法:
要得到list
l
,我只用了不到2秒钟的时间。你知道吗PS:用记事本打开大文件(比如250MB)应该不会有问题,我甚至打开了500MB的文件。你知道吗
相关问题 更多 >
编程相关推荐