簡體   English   中英

Python gzip.open .tell()具有線性增加因子,使其變慢

[英]Python gzip.open .tell() has a linear increasing factor making it slow

使用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()放在debug-counter / timer函數中,使得fh.tell()只執行一次並獲得穩定的65行/秒

我是完全下架還是不應該fh.tell()非常快? 或者這是gzip單獨的副作用?

我曾經手動存儲文件位置,但由於文件結尾,編碼問題等原因,它偶爾也會fh.tell()所以我認為fh.tell()會更准確。

有替代方案還是可以加快fh.tell()的速度?

我使用zlib的經驗(雖然使用它來自C而不是python,但我懷疑問題是一樣的)是尋求是慢的。 zlib不會跟蹤它在文件中的位置,所以如果你尋找它必須從頭開始解壓縮,以便計算它應該尋求的前進多少未壓縮字節。

換句話說,順序讀取或寫入很好。 如果你必須尋求,那么你就是一個受傷的世界。

我更懷疑你可以期待fh.seek(...)表現良好。

gzip使用壓縮算法,其中壓縮事物的方式取決於它之前的數據的整個歷史記錄。 因此,有一個有效的seek操作,你還必須恢復解碼器的內部狀態。

在任何情況下,這里是seek方法的代碼:( 第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調用即可執行搜索 - 即讀取和解壓縮數據,直到它處於正確的文件位置,如果向后搜索,則只需從文件的開頭進行倒帶和向前讀取。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM