在大型文本文件python上搜索

时间:2019-07-04 20:36:14

标签: python seek fseek

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

我看到的问题是,对于较小的文件(<5个演出),这种读取方法效果很好。但是,对于更大的文件(> 20个演出),尤其是当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的使用情况,也没有发现那里有什么忙。

2 个答案:

答案 0 :(得分:0)

解决这个问题的一种好方法是将OS模块newlist= [[4,10,2], [12], [4], [5,4]] (在您的情况下带有标志os.open),os.O_RDONLYos.lseek中的功能组合在一起I / O

答案 1 :(得分:0)

您的代码在我的系统(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)