国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

Python中最快解壓zip文件的方法

開發 后端
挑戰在于這些 zip 文件太大了。它們的平均大小是 560MB 但是其中一些大于 1GB。這些文件中大多數是文本文件,但是其中同樣也有一些巨大的二進制文件。不同尋常的是,每個 zip 文件包含 100 個文件但是其中 1-3 個文件卻占據了多達 95% 的 zip 文件大小。

[[220979]]

假設現在的上下文(LCTT 譯注:context,計算機術語,此處意為業務情景)是這樣的:一個 zip 文件被上傳到一個Web 服務中,然后 Python 需要解壓這個 zip 文件然后分析和處理其中的每個文件。這個特殊的應用查看每個文件各自的名稱和大小,并和已經上傳到 AWS S3 上的文件進行比較,如果文件(和 AWS S3 上的相比)有所不同或者文件本身更新,那么就將它上傳到 AWS S3。

Uploads today

Uploads today

挑戰在于這些 zip 文件太大了。它們的平均大小是 560MB 但是其中一些大于 1GB。這些文件中大多數是文本文件,但是其中同樣也有一些巨大的二進制文件。不同尋常的是,每個 zip 文件包含 100 個文件但是其中 1-3 個文件卻占據了多達 95% 的 zip 文件大小。

最開始我嘗試在內存中解壓文件,并且每次只處理一個文件。在各種內存爆炸和 EC2 耗盡內存的情況下,這個方法壯烈失敗了。我覺得這個原因是這樣的。最開始你有 1GB 文件在內存中,然后你現在解壓每個文件,在內存中大約就要占用 2-3GB。所以,在很多次測試之后,解決方案是將這些 zip 文件復制到磁盤上(在臨時目錄 /tmp 中),然后遍歷這些文件。這次情況好多了但是我仍然注意到了整個解壓過程花費了巨量的時間。是否可能有方法優化呢?

 

原始函數

首先是下面這些模擬對 zip 文件中文件實際操作的普通函數:

  1. def _count_file(fn):
  2. with open(fn, 'rb') as f:
  3. return _count_file_object(f)
  4.  
  5. def _count_file_object(f):
  6. # Note that this iterates on 'f'.
  7. # You *could* do 'return len(f.read())'
  8. # which would be faster but potentially memory
  9. # inefficient and unrealistic in terms of this
  10. # benchmark experiment.
  11. total = 0
  12. for line in f:
  13. total += len(line)
  14. return total

這里是可能最簡單的另一個函數:

  1. def f1(fn, dest):
  2. with open(fn, 'rb') as f:
  3. zf = zipfile.ZipFile(f)
  4. zf.extractall(dest)
  5.  
  6. total = 0
  7. for root, dirs, files in os.walk(dest):
  8. for file_ in files:
  9. fn = os.path.join(root, file_)
  10. total += _count_file(fn)
  11. return total

如果我更仔細地分析一下,我將會發現這個函數花費時間 40% 運行 extractall,60% 的時間在遍歷各個文件并讀取其長度。

 

***步嘗試

我的***步嘗試是使用線程。先創建一個 zipfile.ZipFile 的實例,展開其中的每個文件名,然后為每一個文件開始一個線程。每個線程都給它一個函數來做“實質工作”(在這個基準測試中,就是遍歷每個文件然后獲取它的名稱)。實際業務中的函數進行的工作是復雜的 S3、Redis 和 PostgreSQL 操作,但是在我的基準測試中我只需要制作一個可以找出文件長度的函數就好了。線程池函數:

  1. def f2(fn, dest):
  2.  
  3. def unzip_member(zf, member, dest):
  4. zf.extract(member, dest)
  5. fn = os.path.join(dest, member.filename)
  6. return _count_file(fn)
  7.  
  8. with open(fn, 'rb') as f:
  9. zf = zipfile.ZipFile(f)
  10. futures = []
  11. with concurrent.futures.ThreadPoolExecutor() as executor:
  12. for member in zf.infolist():
  13. futures.append(
  14. executor.submit(
  15. unzip_member,
  16. zf,
  17. member,
  18. dest,
  19. )
  20. )
  21. total = 0
  22. for future in concurrent.futures.as_completed(futures):
  23. total += future.result()
  24. return total

結果:加速 ~10%

 

第二步嘗試

所以可能是 GIL(LCTT 譯注:Global Interpreter Lock,一種全局鎖,CPython 中的一個概念)阻礙了我。最自然的想法是嘗試使用多線程在多個 CPU 上分配工作。但是這樣做有缺點,那就是你不能傳遞一個非可 pickle 序列化的對象(LCTT 譯注:意為只有可 pickle 序列化的對象可以被傳遞),所以你只能發送文件名到之后的函數中:

  1. def unzip_member_f3(zip_filepath, filename, dest):
  2. with open(zip_filepath, 'rb') as f:
  3. zf = zipfile.ZipFile(f)
  4. zf.extract(filename, dest)
  5. fn = os.path.join(dest, filename)
  6. return _count_file(fn)
  7.  
  8.  
  9.  
  10. def f3(fn, dest):
  11. with open(fn, 'rb') as f:
  12. zf = zipfile.ZipFile(f)
  13. futures = []
  14. with concurrent.futures.ProcessPoolExecutor() as executor:
  15. for member in zf.infolist():
  16. futures.append(
  17. executor.submit(
  18. unzip_member_f3,
  19. fn,
  20. member.filename,
  21. dest,
  22. )
  23. )
  24. total = 0
  25. for future in concurrent.futures.as_completed(futures):
  26. total += future.result()
  27. return total

結果: 加速 ~300%

 

這是作弊

使用處理器池的問題是這樣需要存儲在磁盤上的原始 .zip 文件。所以為了在我的 web 服務器上使用這個解決方案,我首先得要將內存中的 zip 文件保存到磁盤,然后調用這個函數。這樣做的代價我不是很清楚但是應該不低。

好吧,再翻翻看又沒有損失。可能,解壓過程加速到足以彌補這樣做的損失了吧。

但是一定記住!這個優化取決于使用所有可用的 CPU。如果一些其它的 CPU 需要執行在 gunicorn 中的其它事務呢?這時,這些其它進程必須等待,直到有 CPU 可用。由于在這個服務器上有其他的事務正在進行,我不是很確定我想要在進程中接管所有其他 CPU。

 

結論

一步一步地做這個任務的這個過程感覺挺好的。你被限制在一個 CPU 上但是表現仍然特別好。同樣地,一定要看看在f1f2 兩段代碼之間的不同之處!利用 concurrent.futures 池類你可以獲取到允許使用的 CPU 的個數,但是這樣做同樣給人感覺不是很好。如果你在虛擬環境中獲取的個數是錯的呢?或者可用的個數太低以致無法從負載分配獲取好處并且現在你僅僅是為了移動負載而支付營運開支呢?

我將會繼續使用 zipfile.ZipFile(file_buffer).extractall(temp_dir)。這個工作這樣做已經足夠好了。

 

想試試手嗎?

我使用一個 c5.4xlarge EC2 服務器來進行我的基準測試。文件可以從此處下載:

  1. wget https://www.peterbe.com/unzip-in-parallel/symbols-2017-11-27T14_15_30.zip

這里的 .zip 文件有 34MB。和在服務器上的相比已經小了很多。

hack.unzip-in-parallel.py 文件里是一團糟。它包含了大量可怕的修正和丑陋的代碼,但是這只是一個開始。 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2015-04-08 15:40:53

php在線解壓解壓zip文件

2021-05-08 00:00:27

JavaScript ZIP文件

2019-10-17 17:15:01

Linux解壓文件命令

2021-12-10 15:22:26

Go Zip 文件

2011-08-15 14:07:53

Objective-C解壓縮ZIP文件

2011-12-30 11:14:41

Javazip

2020-09-09 14:30:24

2012-05-10 09:43:28

2020-12-21 16:00:07

Pythonzip文件密碼

2012-12-26 09:31:44

C#Winform

2013-06-13 09:12:07

LinuxLinux技巧海量文件

2024-06-20 08:09:24

2011-04-06 16:05:29

SQL Server數據導入

2009-03-22 19:19:15

多核多核服務器多核歷史

2020-12-13 17:57:16

加密密碼Python

2025-09-26 03:00:00

JSAPIfor 循環

2024-09-26 12:33:29

JSAPI循環

2025-02-21 10:46:16

JSForEachAPI

2023-12-21 07:30:36

PythonZipfileTarfile

2018-07-05 11:05:10

點贊
收藏

51CTO技術棧公眾號

欧美影视一区二区| 欧美亚州在线观看| 天堂av在线播放| 国产成人午夜电影网| 国产美女精彩久久| 九九亚洲精品| 欧美一乱一性一交一视频| 日本综合视频| 欧美成人中文字幕| 国产精品99久久免费观看| 国产999精品久久久影片官网| 成人中文在线| 久久综合精品一区| 欧美激情一区二区三区蜜桃视频 | 国产视频在线播放| 99视频在线观看一区三区| 日本91av在线播放| 久久爱www.| 这里只有精品视频在线| 手机看片福利在线观看| 亚洲欧洲另类国产综合| 激情网站五月天| 久久九九全国免费| 2019日韩中文字幕mv| 成人毛片老司机大片| 一区二区三区久久网| 三级在线观看视频| 欧美~级网站不卡| 免费观看久久av| 全球成人中文在线| 欧美日韩一本| 欧美猛少妇色xxxxx| 欧美黄色影院| 国产在线观看91精品一区| 欧美不卡一区| 一本久久a久久精品vr综合 | 欧洲成人av| 欧日韩精品视频| jizz在线免费观看| 亚洲精品美女久久久| 日韩不卡免费高清视频| 欧美人在线视频| 欧美wwwww| 神马影院我不卡| 成人动漫一区二区| 亚洲综合欧美激情| 精品久久久久久久久久久| 亚洲卡一卡二| 久久免费精品视频| 99国产一区| 久久成人福利视频| 精品久久久久人成| 国产三级电影在线播放| 久久久伊人欧美| 香蕉av777xxx色综合一区| 韩国日本美国免费毛片| 色欲综合视频天天天| 四虎精品在线观看| 国产日韩欧美一区二区三区四区| 国产一区二区三区四| 首播影院在线观看免费观看电视| 日韩小视频在线观看专区| 大奶在线精品| 国风产精品一区二区| 色哟哟精品一区| 亚洲美女色播| 午夜精品福利一区二区| 亚洲资源在线观看| 日韩免费一级| 偷拍盗摄高潮叫床对白清晰| 一区二区三区日韩精品| 天堂久久午夜av| 亚洲精品中文字幕乱码三区不卡| 亚洲观看高清完整版在线观看| 24小时成人在线视频| 台湾成人av| 欧美一卡在线观看| 欧美日韩hd| 亚洲国产精品成人一区二区在线| 久久精品国产亚洲| 成人av资源网站| 久久毛片亚洲| 麻豆传媒网站在线观看| 亚洲国产欧美日韩精品| 久久精品国产亚洲一区二区三区| 在线一级视频| 亚洲一区二区三区香蕉| 精品欧美aⅴ在线网站| 蜜臀91精品国产高清在线观看| 国产福利电影| 国产欧美精品日韩精品| 午夜视频一区二区| 激情国产一区| 免费在线播放电影| 日韩 欧美 自拍| 美乳少妇欧美精品| 一区二区三区四区av| 久久久国产精品| 超碰中文在线| 超碰在线97免费| 国产精品嫩草影院一区二区| 欧美人狂配大交3d怪物一区| 美美哒免费高清在线观看视频一区二区 | 精品日韩在线播放| 色av吧综合网| 欧美日韩中文字幕在线| 日韩高清国产一区在线| 国产一区二区三区亚洲综合| 欧美性猛交xxx乱久交| 国产精品视频在线观看| 欧美艳星brazzers| 国产一区在线观看视频| 国产一区在线电影| 国产网友自拍视频导航网站在线观看 | 伊人av成人| 日韩av手机在线观看| 精品污污网站免费看| 国产在线观看免费一区| 精品国产乱码久久久久久果冻传媒 | 一区二区免费在线| 国产欧美成人| 亚洲天堂av影院| 成视频免费在线看| 欧美主播一区二区三区美女 久久精品人 | av丝袜在线| 美国成人av| 伊人精品久久久久7777| 国产精品影片在线观看| 国产一区二区三区在线播放免费观看| 亚洲理论在线观看| 高清不卡在线观看av| 欧美啪啪一区| 免费成人av| 成人av福利| 导航福利在线| 国产精品一区二区免费在线观看| 91免费版网站在线观看| 5278欧美一区二区三区| 亚洲欧洲美洲在线综合| 91久久线看在观草草青青| 成人欧美一区二区三区白人| 国产精选一区二区三区| 天堂va蜜桃一区二区三区 | 国产精品国产自产拍高清av| 视频一区二区三区在线| 婷婷综合网站| 成人做爰视频www网站小优视频| 久久精品视频免费看| 久青青在线观看视频国产| 欧美黑人又粗又大又爽免费| 日韩一级性生活片| 激情六月天婷婷| 日韩欧美视频免费在线观看| 男人j进女人j| 国产一级不卡视频| 免费cad大片在线观看| 国产视频在线观看网站| 国产免费xxx| 99热成人精品热久久66| 国产免费人做人爱午夜视频| 黄色一级片播放| 国产免费福利| 青青青在线视频播放| 第四色亚洲色图| www污污在线| 欧美精品电影| 浪潮色综合久久天堂 | 亚洲国产日韩欧美在线99| 亚洲福利小视频| 在线免费看av不卡| 日本国产高清不卡| 欧美中在线观看| 91亚洲人电影| 欧美在线观看视频免费| 国产不卡视频| a级片免费在线观看| 成人午夜sm精品久久久久久久| 男人的天堂久久| 一区二区在线| 成人av电影在线| 亚洲国产一区二区a毛片| 精品国产免费人成在线观看| 久久免费视频这里只有精品| 91视频99| 欧美视频免费播放| 成人影院免费观看| 精品国产乱码久久久久久樱花| 韩国亚洲精品| 亚洲视频免费在线| 亚洲国产成人久久| 国产精品夫妻激情| 无码播放一区二区三区| 日韩在线资源| 日韩成人精品一区二区| 高清不卡在线观看| 欧美午夜激情小视频| 国内成人精品视频| 99热这里只有精品免费| 黄色av网站在线播放| 亚洲xxx拳头交|