繁体   English   中英

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

[英]why readline() is much slower than readlines() in Python?

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

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

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

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

谢谢!

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

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

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

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

#!/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()可以正常工作。

文档中 ,对于file.readline()

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

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

对于readlines()

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

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

因此readlines使用readline函数“多次读取”文件。 其他答案可以更详细地回答每个答案的表现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM