如何使用python以與底層庫相媲美的速度使用gzip/gunzip文件?Python中更快,更好的gunzip(和一般文件輸入/輸出)
tl;dr - Use shutil.copyfileobj(f_in, f_out).
我解壓縮* .gz文件解作爲一個更大的一系列文件處理的一部分,和分析,試圖讓蟒蛇進行「接近」內置的腳本。由於我正在使用的數據量很大,這很重要,而且這似乎是一個很重要的理解。
使用在500MB〜在 'gunzip解' bash命令如下收益:
$time gunzip data.gz -k
real 0m24.805s
一個天真的Python實現是這樣的:
with open('data','wb') as out:
with gzip.open('data.gz','rb') as fin:
s = fin.read()
out.write(s)
real 2m11.468s
不讀取整個文件到內存:
with open('data','wb') as out:
with gzip.open('data.gz','rb') as fin:
out.write(fin.read())
real 1m35.285s
檢查本地計算機緩衝區大小:
>>> import io
>>> print io.DEFAULT_BUFFER_SIZE
8192
使用緩衝:
with open('data','wb', 8192) as out:
with gzip.open('data.gz','rb', 8192) as fin:
out.write(fin.read())
real 1m19.965s
使用盡可能多的緩衝地:
with open('data','wb',1024*1024*1024) as out:
with gzip.open('data.gz','rb', 1024*1024*1024) as fin:
out.write(fin.read())
real 0m50.427s
所以很明顯它是緩衝/ IO約束。
我有一個適度複雜的版本,運行在36秒,但涉及預先分配的緩衝區和嚴密的內部循環。我希望有一個「更好的方法」。
上面的代碼是合理和清晰的,儘管仍比bash腳本慢。但是,如果有一個非常迂迴或複雜的解決方案,它不適合我的需求。我主要的警告是我想看到一個「pythonic」的答案。
當然,總是有這種解決方案:
subprocess.call(["gunzip","-k", "data.gz"])
real 0m24.332s
但對於這個問題的目的,是有處理文件「pythonically」的一個更快的方法。
有時python並不總是答案,那有什麼問題? –
你的例子確實沒有任何意義:python示例的所有三個例子1)只是複製並且根本不解壓2)一次將文件讀入內存3)不受io緩衝的限制。此外,'gunzip'和cpython的'gzip'模塊使用完全相同的底層庫 – user2722968
感謝您的支持。爲必要的編輯道歉。我提前提交了提交。 1)錯過了我的工作代碼中的gzip前綴。現在添加。 2/3)通過緩衝它提高了2倍的速度。 4)是的,它確實使用底層庫,所以我試圖理解它爲什麼這麼慢,特別是考慮到子進程版本和底層庫一樣快。 4b)foo.gz是來自樣本的剪切和粘貼,現在已經修復。 5.)8219是一個錯字。應該是8192,這對應於系統的緩衝區大小並增加了小的速度增加。 – JHiant