使用Python 3.3.5,我有一个代码如下:
with gzip.open(fname, mode='rb') as fh:
fh.seek(savedPos)
for line in fh:
# some work is done
savedPos = fh.tell()
在每一行上完成的工作对系统来说已经非常沉重,所以我并不希望有很多人。但我扔进调试计数器并得到以下结果:
48 rows/sec
28 rows/sec
19 rows/sec
15 rows/sec
13 rows/sec
13 rows/sec
9 rows/sec
10 rows/sec
9 rows/sec
9 rows/sec
8 rows/sec
8 rows/sec
8 rows/sec
8 rows/sec
7 rows/sec
7 rows/sec
7 rows/sec
7 rows/sec
5 rows/sec
...
这告诉我一些事情已经关闭,所以我把fh.tell()
放在调试计数器/计时器函数中,这样fh.tell()
每秒只执行一次并得到一个稳定的 65行/秒
我是完全下架还是不应该非常快?或者这只是gzip的副作用?
我曾经手动存储文件位置,但由于文件结尾不同,编码问题等原因,它偶尔也会出错,所以我认为fh.tell()
会更准确。
有没有其他选择,或者你可以加快fh.tell()的速度吗?
答案 0 :(得分:3)
我使用zlib的经验(尽管使用它来自C而不是python,但我怀疑问题是相同的)是寻求是慢的。 zlib不会跟踪它在文件中的位置,所以如果你寻找它必须从头开始解压缩,以便计算它应该寻求的前进多少未压缩字节。
换句话说,顺序读取或写入很好。如果你必须寻求,那么你就是一个受伤的世界。
答案 1 :(得分:3)
我怀疑你可以期待fh.seek(...)
表现良好。
gzip使用压缩算法,其中压缩事物的方式取决于它之前的数据的整个历史记录。因此,有一个有效的seek
操作,您还必须恢复解码器的内部状态。
无论如何,这是seek
方法的代码:(lines 435-442)
elif self.mode == READ:
if offset < self.offset:
# for negative seek, rewind and do positive seek
self.rewind()
count = offset - self.offset
for i in xrange(count // 1024):
self.read(1024)
self.read(count % 1024)
所以通过执行read
调用来执行搜索 - 即读取和解压缩数据,直到它处于正确的文件位置,如果你向后搜索,它只是从一开始就重新开始并向前读取文件。