【问题标题】:Seek on a large text file python在大文本文件 python 上查找
【发布时间】:2019-07-04 20:36:14
【问题描述】:

我有一些文本文件,其大小介于 5 gigs 和 50 gigs 之间。我正在使用 Python 来阅读它们。我在字节偏移方面有特定的锚点,我可以seek 并从每个文件中读取相应的数据(使用 Python 的file api)。

我看到的问题是,对于相对较小的文件( 20 gigs),尤其是当file.seek 函数必须进行更长的跳转(例如一次几百万字节)时,它(有时)需要几百毫秒才能完成这样做。

我的印象是文件中的查找操作是恒定时间操作。但显然,他们不是。有办法解决吗?

这是我正在做的事情:

import time

f = open(filename, 'r+b')
f.seek(209)
current = f.tell()
t1 = time.time()
next = f.seek(current + 1200000000)
t2 = time.time()
line = f.readline()
delta = t2 - t1

delta 变量间歇性地在几微秒到几百毫秒之间变化。我还分析了 cpu 的使用情况,也没有看到那里有什么忙。

【问题讨论】:

  • 您确定是搜索本身,而不是后续读取需要更长时间吗?我同意你的观点,搜索本身基本上不需要任何时间。如果是读取而不是查找本身,那么我会查看读取背后的缓冲行为。 - 无论哪种情况,我认为您在文件中的位置都无关紧要。
  • 你能提供一个minimal reproducible example吗?
  • 例如:我正在读取文件为:f=open(filename, 'r+b'); f.seek(100000000); ,然后读取一行,如f.readline()
  • 啊,二进制模式,尽管您的问题提到了“文本文件”。但是在我的系统上以 100 MB 的步长寻找一个 2 GB 的文件需要几毫秒的时间。所以我猜这不是 Python 的东西。它可能是您的 Python 解释器的具体实现、您的操作系统/文件系统、病毒扫描程序?我可以想象(但这是猜测)搜索操作可能会在您的计算机上的某个级别上启动预读操作。只是为了争论,您可以在禁用病毒扫描程序的情况下尝试相同的测试,或者使用另一个文件系统上的文件,或者在 Python 中使用类似文件的对象?
  • 正如@Steve 所建议的,它可能是读取本身,而不是搜索。从您评论中的代码中仍然不清楚这一点,这就是我要求minimal reproducible example 的另一个原因。你能说明你是如何测量时间的吗?

标签: python seek fseek


【解决方案1】:

您的代码在我的系统(Windows 10、Python 3.7)上持续运行不到 10 微秒,因此您的代码中没有明显的错误。

注意:您应该使用time.perf_counter() 而不是time.time() 来衡量性能。 time.time() 的粒度可能非常糟糕(“并非所有系统都提供比 1 秒更精确的时间”)。将时间与其他系统进行比较时,您可能会得到奇怪的结果。

我的最佳猜测是查找会触发一些缓冲(预读)操作,这可能会很慢,具体取决于您的系统。

根据文档:

二进制文件以固定大小的块缓冲;缓冲区的大小是通过尝试确定底层设备的“块大小”并回退到io.DEFAULT_BUFFER_SIZE 的启发式方法来选择的。在许多系统上,缓冲区通常为 4096 或 8192 字节长。

您可以尝试通过将参数 buffering=0 添加到 open() 来禁用缓冲,并检查是否有影响:

open(filename, 'r+b', buffering=0)

【讨论】:

  • 谢谢@wovano。让我看看它是否有帮助。这个问题是非常间歇性的,正如我所提到的,我仔细检查了它与 CPU 繁忙或任何事情无关。此外,我在运行测试时确实确保 pagecache/fs 缓存为空。如果我能看到,我会在这里发布我的观察结果。
【解决方案2】:

解决此问题的一个好方法是组合来自 OS 模块 os.open(在您的情况下带有标志 os.O_RDONLY)、os.lseekos.read 的函数,它们位于低级 I/O

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-10-14
    • 2016-05-30
    • 2022-12-02
    • 2022-01-26
    • 1970-01-01
    • 2018-03-28
    • 2019-07-30
    • 1970-01-01
    相关资源
    最近更新 更多