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

时间:2014-04-08 16:18:30

标签: python

在一次采访中,一位采访者问我为什么readline()比Python中的readlines()慢得多?

我回答readlines()需要多次阅读,需要更多支出。

我不知道答案是否正确。

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

谢谢!

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

readlines()一次读取整个文件,readline()只能读取一行。

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

2 个答案:

答案 0 :(得分:9)

为了好玩,我写了一堆迭代文件并将每行放入列表的函数:

#!/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]

以下是使用Python 2.6对69,073行的文件执行操作的方法(注意,这些结果可能在较新版本的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()可以正常工作。

答案 1 :(得分:-1)

来自documentationfile.readline()

  

f。readline()从文件中读取一行;换行符   (\ n)留在字符串的末尾,仅在最后一个省略   文件的行,如果文件没有以换行符结尾。

     

从文件中读取整行。尾随的换行符是   保留在字符串中(但是当文件以。结尾时可能不存在   不完整的线)。如果size参数存在并且   非负数,它是最大字节数(包括尾随数)   换行符)可能会返回不完整的行。当大小不是0时,   仅在立即遇到EOF时才返回空字符串。

对于readlines()

  

如果要阅读列表中文件的所有行,也可以使用   list(f)或f.readlines()。

     

使用readline()读取EOF并返回包含这些行的列表   因此阅读。如果存在可选的sizehint参数,则代替   读取EOF,整行总计大小字节   (可能在四舍五入到内部缓冲区大小之后)被读取。   实现类文件接口的对象可以选择忽略   sizehint如果无法实现,或无法实现   有效。

因此readlines使用readline功能来"多次阅读"文件。其他答案可以更详细地回答每个答案的表现。