Python gzip.open.tell()有一个线性递增因子,使其变慢

Python gzip.open.tell()有一个线性递增因子,使其变慢,python,file-io,gzip,Python,File Io,Gzip,使用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

使用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行/秒

我是不是已经完全下架了,还是fh.tell()不应该非常快?或者这仅仅是gzip的副作用

我曾经手动存储文件位置,但由于不同的文件结尾、编码问题等原因,它偶尔会出错,因此我认为
fh.tell()
会更准确

有其他选择吗,或者你能加快fh.tell()的速度吗?

我使用zlib的经验(虽然是从C而不是python使用它,但我怀疑问题是相同的)是,寻找是缓慢的。zlib不跟踪它在文件中的位置,因此如果您查找它,必须从一开始就解压缩,以便计算它应该查找到的未压缩字节数


换句话说,按顺序读或写是可以的。如果你必须去寻找,你会受到伤害。

我很怀疑你能指望
fh.seek(…)
表现良好

gzip使用一种压缩算法,其中压缩方式取决于之前数据的整个历史。因此,如果执行有效的
seek
操作,您还必须恢复解码器的内部状态

在任何情况下,以下是
seek
方法的代码:()

elif self.mode==读取:
如果偏移量<自偏移量:
#对于负寻道,倒带并进行正寻道
self.rewind()
计数=偏移量-自偏移量
对于X范围内的i(计数//1024):
self.read(1024)
self.read(计数%1024)

因此,查找是通过执行
read
调用来执行的,即读取和解压缩数据,直到数据位于正确的文件位置,如果向后查找,则只需从文件的开头倒回并向前读取。

这肯定能解释我所经历的行为。如果是这样的话,我只有两个选择,要么自己跟踪文件位置,要么牺牲准确性来提高性能。谢谢你的研究,节省了我查看源代码的时间。不应该是很难将zlib全部修补在一起。
   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)