简单、快捷的zip文件创建
项目描述
fastzip
该项目允许您高效地创建和组合zip文件。
“fastzip”中的“fast”是什么意思?
主要有两点
- 多线程压缩(DEFLATE),类似于
- 能够复制/合并zip文件而不重新压缩,类似于
zipmerge
它也是纯Python,能够流式传输输入(不需要中央目录存在),并具有基于规则的压缩方法选择器,以避免增加小型文件的大小。
演示
与ZipFile相似的API
from pathlib import Path
from fastzip.write import WZip
with WZip(Path("out.zip")) as z:
z.write(Path("a"))
合并现有文件
from fastzip.read import RZipStream
from fastzip.write import WZip
with WZip(Path("out.zip")) as z:
for entry in RZipStream("zip1.zip").entries():
z.enqueue_precompressed(*entry)
for entry in RZipStream("zip2.zip").entries():
z.enqueue_precompressed(*entry)
如果您想自定义线程数、压缩选择、归档中的文件名等,这些都是可能的。现在请查看源代码,但基本思路是
from io import BytesIO
from pathlib import Path
from fastzip.write import WZip
from fastzip.chooser import CompressionChooser
force_store = CompressionChooser(default="store")
with WZip(Path("out.zip"), threads=2, chooser=force_store) as z:
z.write(Path("a"), archive_path=Path("inzipname"), synthetic_mtime=0, fobj=BytesIO(b"foo"))
基准测试
在8核和12核xeon上测试,对于足够大的工作负载,它分别能够使用约7.5和11个核心。有关瓶颈的更多信息,请参见下一节。
$ dd if=/dev/urandom of=a bs=1M count=512
512+0 records in
512+0 records out
536870912 bytes (537 MB, 512 MiB) copied, 2.17395 s, 247 MB/s
$ ./demo.sh
+ rm -f a.zip a1.zip a2.zip
+ cat a
+ /usr/bin/time zip -o a.zip a
adding: a (deflated 0%)
11.35user 0.24system 0:11.60elapsed 99%CPU (0avgtext+0avgdata 2892maxresident)k
24inputs+1048752outputs (1major+205minor)pagefaults 0swaps
+ /usr/bin/time python -m zipfile -c a1.zip a
12.61user 0.44system 0:14.53elapsed 89%CPU (0avgtext+0avgdata 11360maxresident)k
0inputs+1048920outputs (0major+1623minor)pagefaults 0swaps
+ /usr/bin/time python -m fastzip -c -o a2.zip a
20.39user 0.56system 0:02.78elapsed 753%CPU (0avgtext+0avgdata 1079140maxresident)k
0inputs+1048968outputs (0major+149864minor)pagefaults 0swaps
+ ls -l a.zip a1.zip a2.zip
-rw-r--r-- 1 tim tim 537034782 Nov 16 13:47 a1.zip
-rw-r--r-- 1 tim tim 537037407 Nov 16 13:47 a2.zip
-rw-r--r-- 1 tim tim 536957493 Nov 16 13:01 a.zip
性能瓶颈
可能有多个。以下是一些我观察到的包括
- 慢速覆盖性能(在ext4上);这就是为什么WZip只以'xb'模式打开的原因。
- 小文件a. 慢速状态(即使在ramdisk上也为0.5mS)b. zlib.crc32不释放gil < 5KiB c. 小文件消耗了文件预算而没有取得很大进展(将顺序重新排序以在每个(file_budget-1)处有一个大文件可能会减少停滞
- 小的输出缓冲区(WZip现在以1MB打开)
- 查找(这需要刷新输出缓冲区)
- ThreadPoolExecutor巨锁(提交future需要获取两个锁,但其中一个是全局锁以检测解释器关闭?)
- Deflate块大小(较小的块意味着在中等大小文件上更好的并行性和更少的IO阻塞,但也需要调度更多的future、crc32调用和crc32_combine)。较大的块大小也意味着略好的压缩率。
- 垃圾回收(最近对并行性的调整似乎增加了垃圾回收的量)
- 混合使用deflate和zstd -- 虽然线程数量通常在它们之间共享,但在切换时仍可能出现停滞和溢出。
如果有疑问,请生成跟踪,并查找瓶颈(无论是空白时间,即没有进行有用的工作,还是除了压缩本身之外似乎需要很长时间的任何操作)。
示例跟踪
这个跟踪仅在中间标记为“acquire”的部分表现良好 -- 那里运行耗尽了一些资源,无法再排队更多数据,但压缩线程仍在全力工作。看似未标记的黄金事件是垃圾回收,你可以看到CPU图通常相当低。
这是中间部分的放大图,你可以更清楚地看到压缩线程很忙,I/O线程有一些空闲时间。MainThread中的差距意味着存在一些隐藏的工作。
未来计划(来自缺点)
近期问题
- 线程中发生的错误并不总是以明显的方式报告。
- 添加目录(而不是文件)是串行的。
- 文件必须是可MMAP的,在32位系统上这可能会耗尽进程地址空间。
- 存在一个打开文件预算,但没有正式的内存预算;输出未来可能大约缓冲最大的文件大小的两倍,在内存中。例如,上面的512MB文件峰值内存约为1GB。
WZip
太复杂,方法太多。这使得它难以重构和扩展。- 验证不足(例如,重复的文件名,包含".."的文件名),并且对存档名代码是否稳固并不完全确定。
注意:API预计在1.0版本之前会改变几次;如果您要将依赖关系添加到此项目(例如,如果您使用假设的版本0.4
,请确保指定>=0.4, <0.5
)。
许可证
fastzip版权所有Tim Hatch,并使用MIT许可证许可。我在此仓库中向您提供代码,属于开源许可证。这是我的个人仓库;您从我那里获得的代码许可证来自我,而不是我的雇主。有关详细信息,请参阅LICENSE
文件。
项目详情
下载文件
下载适合您平台的文件。如果您不确定选择哪个,请了解更多关于安装软件包的信息。
源代码分布
fastzip-0.5.0.tar.gz (374.3 kB 查看哈希)
构建分布
fastzip-0.5.0-py3-none-any.whl (19.8 kB 查看哈希)
关闭
fastzip-0.5.0.tar.gz的哈希
算法 | 哈希摘要 | |
---|---|---|
SHA256 | e6f435a69b07a740fb179b87d6b6d234abc98195661df044114e34bda6d8cb3b |
|
MD5 | 70f7b961fd576e1cbf09e99176eca62b |
|
BLAKE2b-256 | b26b20e8d337c69098a384c738149dcc7d9101c419704b75b6770db6ffba1062 |
关闭
fastzip-0.5.0-py3-none-any.whl的哈希值
算法 | 哈希摘要 | |
---|---|---|
SHA256 | 2538eef401fbc544431bbf20f901de550c1090cdc7d8e1d12f12018b0bbe6118 |
|
MD5 | 64c0e26c98dac1f770ea49a13af59155 |
|
BLAKE2b-256 | 5de5ce64e288cadcc7bdc9cf5ef4a1693bde732dc08fdc8875ec83c755811ea6 |