我有一些文本文件,其大小在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的使用情况,也没有发现那里有什么忙。
答案 0 :(得分:0)
解决这个问题的一种好方法是将OS模块newlist= [[4,10,2], [12], [4], [5,4]]
(在您的情况下带有标志os.open
),os.O_RDONLY
,os.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)