【问题标题】:Reading a file using range function使用范围函数读取文件
【发布时间】:2019-01-28 12:13:06
【问题描述】:

我正在分块读取一个大文件,例如

>  def gen_data(data):
>             for i in range(0, len(data), chunk_sz):
>                 yield data[i: i + chunk_sz]

如果我使用长度变量而不是 len(data) ,类似的东西

length_of_file = len(data)
def gen_data(data):
    for i in range(0, length_of_file, chunk_sz):
        yield data[i: i + chunk_sz]

大文件的性能改进是什么。我测试了小的,但没有看到任何变化。

P.S 我来自 C/C++ 背景,在 while 或 for 循环中计算每次重复是一种不好的做法,因为它会为每次调用执行。

【问题讨论】:

  • 您不是“使用范围函数读取文件”-文件是流...您不能像这样对它们进行索引。如果您已经完全在data 中获取了文件数据.. 为什么要分块呢?
  • 另一方面,由于您在函数内部使用变量length_of_file,因此最好在函数本身中定义它以避免与全局变量(如果有任何同名)发生任何可能的冲突.所以把length_of_file = len(data)放在函数中for循环之前

标签: python performance file for-loop range


【解决方案1】:

使用此代码将大文件读入块:

def read_in_chunks(file_object, chunk_size=1024):
    """Lazy function (generator) to read a file piece by piece.
    Default chunk size: 1k."""
    while True:
        data = file_object.read(chunk_size)
        if not data:
            break
        yield data


f = open('really_big_file.dat')
for piece in read_in_chunks(f):
    process_data(piece)

另一个使用 iter 的选项

f = open('really_big_file.dat')
def read1k():
    return f.read(1024)

for piece in iter(read1k, ''):
    process_data(piece)

【讨论】:

    【解决方案2】:

    Python 的 for 循环不是 C for 循环,而是真正的 foreach 循环。在你的例子中:

    for i in range(0, len(data), chunk_sz):
    

    range() 只调用一次,然后 python 迭代返回值(python2 中的 list,python3 中的可迭代 range 对象)。 IOW,从这个 POV 来看,您的 sn-ps 是等效的 - 不同之处在于第二个 sn-p 使用非局部变量 length_of_file,因此您实际上会从解决它中获得性能。

    我来自 C/C++ 背景,在 while 或 for 循环中计算每次重复是一种不好的做法,因为它会为每次调用执行

    搁置了最终的编译器优化,这对于大多数(如果不是所有)语言都是如此。

    正如 cmets 或答案中已经提到的其他人所说的那样:这不是您以块读取文件的方式 - 您想要 SurajM 的第一个 sn-p。

    【讨论】:

      猜你喜欢
      • 2016-10-10
      • 2015-10-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-24
      • 2021-02-13
      • 1970-01-01
      • 2014-03-06
      相关资源
      最近更新 更多