【问题标题】:Reading a binary file in Python: takes a very long time to read certain bytes在 Python 中读取二进制文件:读取某些字节需要很长时间
【发布时间】:2011-01-16 23:30:51
【问题描述】:

这很奇怪

我正在使用 Python 中的 numpy 库读取一些(当然非常大:每个约 2GB)二进制文件。 我正在使用:

thingy = np.fromfile(fileObject, np.int16, 1)

方法。 这正好在一个嵌套循环的中间——我每个“通道”循环 4096 次,这个“通道”循环每个“接收器”循环 9 次,这个“接收器”循环 4 次(有 9 个通道每个接收器,其中有 4 个!)。这是针对每个“块”的,其中每个文件大约有 3600 个。

所以你可以看到,非常迭代,我知道这需要很长时间,但它比我预期的要长很多 - 每个“块”平均需要 8.5 秒。

我使用 time.clock() 等运行了一些基准测试,发现一切都以应有的速度进行,除了每个“块”大约 1 或 2 个样本(因此 4096*9*4 中的 1 或 2 个样本),其中它似乎会“卡住”几秒钟。现在这应该是从二进制返回一个简单的 int16 的情况,而不是应该花几秒钟的时间......为什么它会粘住?

从基准测试中我发现它每次都停留在相同的位置(第 2 块,接收器 8,通道 3,样本 1085 就是其中之一,记录在案!),它会卡在那里大约每次运行的时间相同。

有什么想法吗?!

谢谢,

邓肯

【问题讨论】:

  • 我猜是从0开始计数的吧?
  • 是的,所以接收器 0-3,通道 0-7,样本 0-4095
  • fromfile() 之类的问题在于它无法提前知道要分配多少空间,因此对于非常大的文件,您可能会被搞砸。请参阅我的回答和stackoverflow.com/questions/1896674/… 中的以下一些 cmets,了解有关如何处理此问题的可能想法以及潜在问题。
  • Peter - 谢谢你,问题是我不想同时存储所有内容。我只是在读取可管理的数据块(最大约 2mb),用它们计算东西,将结果写入文件然后重复。似乎我完成的那个没有被处理/垃圾收集。明天回去工作时,我会尝试其中一些解决方案。
  • 我完成的那些没有被处理掉——完成后试试del xx?可能会更快,可能不会

标签: python binary numpy binaryfiles


【解决方案1】:

会不会是garbage collection 加入了名单?

补充:是有趣的数据,还是blockno?如果你按照随机顺序读取块会发生什么

r = range(4096)
random.shuffle(r)  # inplace
for blockno in r:
    file.seek( blockno * ... )
    ...

【讨论】:

    【解决方案2】:

    您将结果存储在哪里?当 list/dicts/whatever 变得非常大时,需要重新分配和调整大小时可能会出现明显的延迟。

    【讨论】:

    • 嗯,基本上它们都存储在列表中的列表中,然后整个数据集(每个“块”)与标题信息一起存储在类的实例中。这不应该超过一兆字节……除非 Python 不处理列表?我可以强迫它这样做吗?
    【解决方案3】:

    虽然很难说没有某种可重现的样本,但这听起来像是一个缓冲问题。第一部分是缓冲的,直到你到达缓冲区的末尾,它很快;然后它会减速,直到下一个缓冲区被填满,依此类推。

    【讨论】:

    • 是的,这听起来很可能,你知道我可以测试这个的方法吗?或者可能的缓冲区大小是多少?
    • 好吧,至少要确定 gnibbler 还是我更接近解决方案的一件事是运行它并立即丢弃结果。如果仍然出现减速,则更有可能是缓冲问题。然后也许看看手动阅读而不是通过numpy 是否会改变任何东西。
    • 当然,很抱歉一直问新问题,但是如何在 Python 中“扔掉”一个对象?多年来,我一直试图找出有关 dispose 等的信息,但在任何地方都找不到。
    • 您可以使用gc.collect() (docs.python.org/library/gc.html) 来强制进行垃圾回收,但我的意思是简单地读取而不将结果分配给任何东西。
    • 另一种测试是否是由文件缓冲引起的方法是在文件 open() 函数中更改缓冲区大小。默认是使用操作系统的默认大小。查看更改它是否会更改暂停发生的位置。注:设置缓冲区大小不适用于所有操作系统 - 请参阅文档。
    猜你喜欢
    • 2014-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-06
    • 2014-03-19
    • 1970-01-01
    • 2011-12-26
    • 1970-01-01
    相关资源
    最近更新 更多