【发布时间】:2011-07-01 20:28:50
【问题描述】:
我想在我的代码中读取一个大文件。为此,read() 或 readline() 更快。循环怎么样:
for line in fileHandle
【问题讨论】:
我想在我的代码中读取一个大文件。为此,read() 或 readline() 更快。循环怎么样:
for line in fileHandle
【问题讨论】:
对于文本文件,只需使用for 循环对其进行迭代几乎总是可行的方法。别管速度,它是最干净的。
在 python 的某些版本中,readline() 确实只读取一行,而for 循环读取大块并将它们分成几行,因此它可能更快。我认为最新版本的 Python 也为 readline() 使用缓冲,因此性能差异将是微乎其微的(for 可能仍然在微观上更快,因为它避免了方法调用)。然而,出于性能原因选择其中一个可能是过早的优化。
编辑添加:我刚刚查看了一些 Python 发行说明。 Python 2.5 说:
现在混合迭代是非法的 带有 for line in file 的文件和 调用文件对象的 read()/readline()/readlines() 方法。
Python 2.6 引入了 TextIOBase,它同时支持迭代和readline()。
Python 2.7 修复了交织 read() 和 readline()。
【讨论】:
如果文件很大,read() 绝对是个坏主意,因为它会将整个文件加载(没有大小参数)到内存中。
Readline 一次只读取一行,所以我会说这是大文件的更好选择。
并且仅仅迭代文件对象应该和使用 readline 一样有效。
更多信息请见http://docs.python.org/tutorial/inputoutput.html#methods-of-file-objects
【讨论】:
readline 对迭代器的缓冲区一无所知:参见 PEP 234,它说迭代器因此要快得多。然而,当人们试图将readline 调用混合到迭代器循环的中间时,这会导致问题,因此它在更高版本中得到修复,现在readline 使用相同的缓冲区。我不确定究竟是哪个版本:2.7 修复了交叉 read 和 readline 的问题,但我认为 readline 和迭代器修复更早。
readlines 的文档表明有一个可选的大小提示。因为它太模糊了,很容易被忽略,但我发现这通常是读取文件的最快方法。使用 readlines(1),它提示一行,但实际上读取了大约 4k 或 8k 行 IIRC。这利用了操作系统的缓冲,并在不使用过多内存的情况下稍微减少了调用次数。
您可以尝试不同大小的 sizehint,但我在测试时发现 1 在我的平台上是最佳的
【讨论】:
如果你有足够的内存,如果性能是一个问题,请使用 readline。我已经看到,在使用 gzip 文件时:read().split('\n') 需要 5 秒来循环,而使用迭代器需要 38 秒。 GZ 文件大小约为 45 MB。
【讨论】:
read() 基本上是在尝试读取整个文件并将其保存为单个字符串以供以后使用,而 readlines() 也在尝试读取整个文件,但它会执行 split("\n") 和将行的字符串存储到列表中。因此,如果文件过大,这两种方法都不是首选。
readline() 和 for 循环(即文件中的行:)将一次读取一行并将其存储到一个字符串中。我猜如果记忆允许,他们会在同一时间完成工作。但是,如果文件很大,则首选这两个。
【讨论】:
如果您的文件是文本文件,则使用 readlines() 这显然是读取包含行的文件的方法。除此之外:如果您真的意识到可能的性能问题,请执行基准测试。我怀疑你会遇到任何问题......文件系统的速度应该是限制因素。
【讨论】:
huge file 的含义,readlines() 可能不是一个好主意。
read(),readlines() 将整个文件读入内存。如果这对您来说可能是个问题,那么readline()(不!)和迭代器启用的零碎策略是更好的选择。
read() 和 readlines() 的真正区别 read 函数只是将文件按原样加载到内存中。 readlines 方法将文件作为没有行终止的行列表读取。 readlines 方法应该只用于文本文件,而不应该用于大文件。 如果从文本文件中复制信息,read 效果很好,因为它可以使用 write 函数输出,而无需添加行终止。
【讨论】:
两者都没有。他们都将内容读入内存。 在大文件的情况下,遍历文件对象一次只加载一行文件,这可能是处理大文件内容的好方法。
【讨论】: