【问题标题】:python unzip -- tremendously slow?python unzip - 非常慢?
【发布时间】:2026-01-22 18:45:02
【问题描述】:

谁能解释一下下面的谜团?

我创建了一个大小约为 37[MB] 的二进制文件。在 Ubuntu 中压缩它——使用终端——花费不到 1[秒]。然后我尝试了 python:以编程方式压缩它(使用 zipfile 模块)也花了大约 1[sec]。

然后我尝试解压缩我创建的 zip 文件。在 Ubuntu 中——使用终端——这花费了不到 1[秒]。

在 python 中,解压缩代码(使用 zipfile 模块)运行时间接近 37[秒]!任何想法为什么?

【问题讨论】:

  • 你能把你压缩文件的部分贴出来吗?这样,我们可以做出更准确的 cmets。
  • 我猜 python zip/unzip 代码被解释而不是调用某些(编译的 C)库。
  • @TomMD:实际上不是,因为它依赖于 zlib,至少在文件实际被压缩时是这样。实际的解压缩是在本机代码中完成的。比较未压缩 zip 文件时的解压缩时间可能是值得的,以查看效果是否来自解释。
  • 也许您没有有效地处理解压缩数据流。由于内存分配和交换,在内存中加载 37 MB 大小的字符串肯定需要很长时间。您应该将输出直接发送到文件。你是如何使用zipfile模块解压压缩文件的?
  • @scoffey:我很难相信内存分配/交换会花费那么的时间。 37 MB 什么都不是,即使在 Python 中也是如此。

标签: python linux ubuntu zip unzip


【解决方案1】:

我也在努力使用 Python 解压缩/解压缩/提取 zip 文件,并且“创建 ZipFile 对象,循环通过其 .namelist(),读取文件并将它们写入文件系统”低级方法没有看起来很Python。所以我开始挖掘zipfile objects,我认为它没有很好地记录并涵盖所有对象方法:

>>> from zipfile import ZipFile
>>> filepath = '/srv/pydocfiles/packages/ebook.zip'
>>> zip = ZipFile(filepath)
>>> dir(zip)
['NameToInfo', '_GetContents', '_RealGetContents', '__del__', '__doc__', '__enter__', '__exit__', '__init__', '__module__', '_allowZip64', '_didModify', '_extract_member', '_filePassed', '_writecheck', 'close', 'comment', 'compression', 'debug', 'extract', 'extractall', 'filelist', 'filename', 'fp', 'getinfo', 'infolist', 'mode', 'namelist', 'open', 'printdir', 'pwd', 'read', 'setpassword', 'start_dir', 'testzip', 'write', 'writestr'] 

“extractall”方法就像tarfile's extractall 一样工作! (在 python 2.6 和 2.7 但不是 2.5)

然后是性能问题;文件 ebook.zip 为 84.6 MB(主要是 pdf 文件),未压缩文件夹为 103 MB,在 MacOSx 10.5 下默认压缩为“存档实用程序”。所以我对 Python 的 timeit 模块做了同样的事情:

>>> from timeit import Timer
>>> t = Timer("filepath = '/srv/pydocfiles/packages/ebook.zip'; \
...         extract_to = '/tmp/pydocnet/build'; \
...         from zipfile import ZipFile; \
...         ZipFile(filepath).extractall(path=extract_to)")
>>> 
>>> t.timeit(1)
1.8670060634613037

在一台负载较重且 90% 的内存正被其他应用程序使用的机器上,耗时不到 2 秒。

希望这对某人有所帮助。

【讨论】:

  • 哇,zipfile 对象文档在我给出这个答案的第二天就在 docs.python.org 上更新了。也许是一些输出问题或 python 做得很好!
  • 好消息!但是,如果我们只需要访问一些文件,或者以某种方式处理它们而不是仅仅解压缩它们,恐怕这将无济于事:(
【解决方案2】:

我不知道您使用什么代码来解压缩文件,但以下代码对我有用:创建仅包含一个文件“file1”的 zip 存档“test.zip”后,以下 Python 脚本提取“file1”来自存档:

from zipfile import ZipFile, ZIP_DEFLATED
zip = ZipFile("test.zip", mode='r', compression=ZIP_DEFLATED, allowZip64=False)
data = zip.read("file1")
print len(data)

这几乎不需要时间:我尝试了一个 37MB 的输入文件,该文件压缩成一个 15MB 的 zip 存档。在这个例子中,Python 脚本在我的 MacBook Pro 上耗时 0.346 秒。也许在您的情况下,这 37 秒被您对数据所做的事情占用了?

【讨论】:

  • 只读取一个文件很容易 - 但是一个包含许多小压缩文件的大型 zip 存档对我来说运行速度非常慢。可能是 zip 中的文件查找效率低下?
【解决方案3】:

我们可以使用 ubuntu 在 python 中提供的 zip,而不是使用 python 模块。我使用它是因为有时 python zip 会失败。

import os

filename = test
os.system('7z a %s.zip %s'% (filename, filename))

【讨论】:

  • 您应该使用 str.format() 而不是 % 格式,例如 os.system('7z a {0}.zip {0}'.format(filename))。正如他们在docs 中提到的那样,它将在未来被删除,我相信它已经在 3+ 中消失了。
  • @thegrinner 错了。应该完全避免这种方法,而是使用import subprocess; subprocess.call(['7z', 'a', filename+'.zip', filename])。或者如果文件名包含空格或换行符会发生什么?
最近更新 更多