为什么Python中的readline()比readlines()慢得多?

11 人关注

在一次面试中,一位面试官问我,为什么Python中的 readline() 要比 readlines() 慢很多?

我回答说 readlines() 需要读很多遍,这需要更多的花费。

我不知道我的答案是否正确。

如果我的答案是正确的,那么支出是多少?

PS:我知道 readline() readlines() 的区别!!。

替换代码1】一次性读取整个文件,而 readline() 只能读取一行。

我希望有人能告诉我一些关于从磁盘上输入文件的知识。

1 个评论
llrs
欢迎来到StackOverflow!你是否读过 文件 ?
python
Apache
Apache
发布于 2014-04-09
2 个回答
dano
dano
发布于 2014-04-09
已采纳
0 人赞同

只是为了好玩,我写了一堆函数,在一个文件上迭代,并把每一行放到一个列表中。

#!/usr/bin/python
def readlines():
    with open("sorted_output.txt") as f:
        line = f.readlines()
def readline():
    with open("sorted_output.txt") as f:
        line = f.readline()
        lines = []
        while line:
            lines.append(line)
            line = f.readline()
def iterate():
    with open("sorted_output.txt") as f:
        lines = []
        for line in f:
            lines.append(line)
def comprehension():
    with open("sorted_output.txt") as f:
        lines = [line for line in f]

下面是它们各自在一个有69,073行的文件上的表现,使用Python 2.6(注意,这些结果在较新版本的Python上可能有所不同)。

dano@hostname:~> python -mtimeit -s 'import test' 'test.readline()'
10 loops, best of 3: 78.3 msec per loop
dano@hostname:~> python -mtimeit -s 'import test' 'test.readlines()'
10 loops, best of 3: 21.6 msec per loop
dano@hostname:~> python -mtimeit -s 'import test' 'test.comprehension()'
10 loops, best of 3: 23.6 msec per loop
dano@hostname:~> python -mtimeit -s 'import test' 'test.iterate()'
10 loops, best of 3: 33.3 msec per loop

所以,readlines()在这里是最快的,尽管使用列表理解对每一行进行迭代几乎与之匹配。我的猜测是,每种方法的速度差异主要是Python中函数调用的高开销造成的(需要的函数调用越多,方法越慢),但也可能有其他因素。希望比我更有见识的人能够对此发表意见。

除了性能之外,在决定使用哪种方法时,还有一个重要的考虑因素是内存成本。使用readlines()会一次将整个文件读入内存。如果你正在处理一个巨大的文件,如果你试图一次性将整个文件读入内存,可能会导致严重的性能问题,或者使程序完全崩溃。在这种情况下,你会想使用iterate()的方法,因为它一次只读一行到内存。如果你只是对每一行进行某种处理,然后把它扔掉,这通常是个好办法,即使它比readlines()稍慢一些,因为你不会受到同样的内存冲击。当然,如果你最终的目标是将整个文件存储在一个 Python 列表中,那么无论如何你都要付出内存的代价,所以 readlines() 会工作得很好。

llrs
llrs
发布于 2014-04-09
0 人赞同

From the 文件 , for file.readline()

f. readline() 从文件中读取一个单行;换行字符 (n)被留在字符串的末尾,并且只有在文件的最后一行没有换行的情况下才会省略。 如果文件不以换行符结尾,则只在文件的最后一行省略。

从文件中读取一整行。后面的换行符被保留在 保留在字符串中(但当文件以不完整的行结束时可能没有 不完整的行)。如果size参数存在并且是 非负数,它是一个最大的字节数(包括尾部的换行符),并且不完整的行也会被保留。 换行),可能会返回一个不完整的行。当size不为0时。 只有在立即遇到EOF的情况下才会返回一个空字符串。

而对于 readlines()

如果你想在一个列表中读取一个文件的所有行,你也可以使用 list(f) 或 f.readlines()。

使用readline()读到EOF为止,并返回一个包含读到的行的列表。 的列表。如果有可选的sizehint参数,那么就不会再读到EOF。 读取到EOF,而是读取整行,总长度约为sizehint字节。 (可能在四舍五入到内部缓冲区大小之后)被读取。 实现类文件接口的对象可以选择忽略