rustgzip 0.5.2
给 Python 3.4 及更新版本使用的 Rust gzip 加速包,导入名为 rustgzip。
本版发布稳定 Python 接口,并附带最新 Rust 研究源码;实验多核解压尚未开放 Python 入口,默认路径仍为顺序原生解压。详见 RELEASE-052.md。
1. 适合解决什么问题
适合顺序读取/写入 .gz、扫描 gzip 完整性和内存压缩解压。
Python 负责文件对象适配,Rust 负责 gzip 解析、DEFLATE、CRC32 和文件流循环。
动态库用 ctypes 加载,不依赖 CPython ABI,不需要 PyO3,不需要安装 isal/based58 等库。
生成的是标准 gzip,不是新格式,系统 gzip 和 Python 标准库都能解压。 支持多个 gzip member 串接及 member 后的零填充;非零尾部垃圾、截断、CRC/ISIZE 错误会报错。
2. 内网 UOS 安装
交付的 rustgzip-0.5.2-py3-none-linux_x86_64.whl 用于 x86_64 Linux。
它在 Debian 10 / glibc 2.28 环境构建,并用真实 Python 3.4.10 和 3.7 验证。
本次没有连接你的内网 UOS;实际发行版兼容性仍以运行结果为准。
安装后不需要 Rust 编译器,不需要联网。不是 ARM、龙芯或 Windows 安装包。
将 wheel 传到内网后执行;根据实际命令名调整 python3.4:
python3.4 -m pip install --no-index --no-deps ./rustgzip-0.5.2-py3-none-linux_x86_64.whl
python3.4 -c "import rustgzip; print(rustgzip.backend_info())"
没有 root 权限时,加 --user,或使用 --target ./py-libs:
python3.4 -m pip install --no-index --no-deps --target ./py-libs ./rustgzip-0.5.2-py3-none-linux_x86_64.whl
PYTHONPATH="$PWD/py-libs" python3.4 your_script.py
没有 pip 时,可以解压 rustgzip-0.5.2-linux_x86_64-portable.zip,将其中的
rustgzip 文件夹与自己的脚本放在同一目录。文件夹内的 .py 和 .so 都要保留。
这是完整的独立包,不需要把整个源码或 vendor 放进内网。
3. 直接替换你的读取代码
import rustgzip as gzip
with gzip.open(stage_file, 'rb') as handle:
while handle.read(1024 * 1024):
pass
如果目的只是确认压缩包是否完整,可以进一步减少 Python 循环:
import rustgzip
try:
size = rustgzip.verify(stage_file)
print('校验成功,解压后大小:%d 字节' % size)
except OSError as exc:
print('校验失败:%s' % exc)
verify 在 Rust 内部循环,复用 1 MiB 缓冲,不生成解压文件。
读取前几块、read(0) 或仅关闭文件,不等于完整性校验;必须完整读到 EOF。
4. 其他常用方式
import rustgzip as gzip
# 二进制写入。with 结束时会写完 gzip 尾部并处理磁盘错误。
with gzip.open('output.gz', 'wb', compresslevel=6) as handle:
handle.write(b'hello\n')
# 文本写入与逐行读取;Python 3.4 不支持 f-string,因此示例也不使用。
with gzip.open('text.gz', 'wt', encoding='utf-8') as handle:
handle.write('中文内容\n')
with gzip.open('text.gz', 'rt', encoding='utf-8') as handle:
for line in handle:
print(line.rstrip('\n'))
# 追加会新建一个标准 gzip member,不修改既有 member。
with gzip.open('output.gz', 'ab') as handle:
handle.write(b'next\n')
packed = gzip.compress(b'hello', compresslevel=1)
plain = gzip.decompress(packed, max_output_size=16 * 1024 * 1024)
# 大文件读取时可复用 bytearray,减少 Python 分配。
buffer = bytearray(1024 * 1024)
with gzip.open('output.gz', 'rb') as handle:
while True:
count = handle.readinto(buffer)
if not count:
break
# 在这里处理 buffer[:count];需要避免复制时使用 memoryview(buffer)[:count]。
5. API 与边界
| 接口 | 行为 |
|---|---|
open(path, mode='rb', compresslevel=6, encoding=None, errors=None, newline=None, buffering=262144) |
顺序文件流,支持 rb/wb/ab/xb 和文本模式 |
GzipFile(path, ...) |
路径式便捷函数,不是标准库同名类 |
compress(data, compresslevel=6) |
bytes-like → gzip bytes,级别 0~9 |
decompress(data, max_output_size=536870912) |
完整解压,默认最多 512 MiB 输出 |
verify(path, chunk_size=1048576) |
完整校验并返回解压字节数;块大小 1 字节~64 MiB |
backend_info() |
返回后端、包和 Python 版本,验证动态库是否可加载 |
- 支持 str/bytes 路径和现代 Python Path;支持 read/readinto/readline/迭代/write/flush/with。
- 不是标准库 gzip 的完整替代品:不支持 seek/rewind、fileobj、fileno、mtime 参数或标准库类继承契约。
tell()返回处理后的逻辑字节位置;不能用它设置文件偏移。文本层有自己的位置规则。- gzip 时间戳固定为 0,不存源文件名;压缩后的字节不保证与标准库逐字节一致。
flush()不是 fsync;成功关闭不等于已经保证断电持久化。wb会截断既有文件,出错可能留下不完整输出。希望防覆盖时用xb;重要输出建议先写临时文件,成功关闭后再由应用原子替换。- 读取坏文件可能先得到部分数据,直到 CRC/EOF 检查时报错;不要在校验前把这些数据当成已验证结果。
- 文件流不限制解压总量;超大/不可信输入应由应用限制处理大小或时间。
- 内存解压的 max_output_size 限制输出字节数,实际峰值内存还包括输入、Rust 缓冲与 Python 返回副本。
- Rust 原生调用期间释放 GIL;不同文件流可以由线程并发处理。普通单 member gzip 没有多核并行解压。
- 打开流后不要 fork 并复用它;子进程应重新打开自己的流。
6. 实测性能怎么看
benchmark-linux-py34.json 是 Debian 10 构建虚拟机、Python 3.4.10、zlib 1.2.11 的结果。
每类输入 16 MiB,每项测三轮取中位数;文件测试包含操作系统缓存,不是冷磁盘吞吐测试。
| 操作 | 本次相对 Python 3.4 标准库 |
|---|---|
| 内存压缩 | 约 1.50~3.23 倍 |
| 内存解压 | 约 2.56~4.62 倍 |
| open 分块读完 | 约 2.25~4.06 倍 |
| verify 整文件校验 | 约 3.04~3.82 倍 |
输入包含重复日志、变化字段的结构化日志和随机数据;不能推广为所有文件的速度保证。
Windows / Python 3.14 的内存解压测试有些比标准库慢,结果也如实保留在
benchmark-windows.json。不要用旧版 Python 的相对加速比推断新版 Python。
在真实 UOS 上复测:
python3.4 tools/benchmark.py 16 benchmark-my-uos.json
python3.4 tests/test_api.py
完整源码包内有这些脚本;测试使用临时生成的数据,不上传用户文件。
7. 后端与许可证
后端使用公开的 flate2 和
zlib-rs,开启运行时 CPU 特性检测。
构建不使用 target-cpu=native,避免在不支持本机指令集的 UOS CPU 上直接崩溃。
未复制 python-isal、python-zlib-ng 或 rapidgzip 实现,也没有将其性能宣传当作本包实测。
本项目新增封装为 MIT;依赖许可、版权告知、精确版本和来源说明见
PROVENANCE.md、THIRD_PARTY_LICENSES/。源码包附带公开 vendor,可离线构建,
未包含私有源码、密钥、运行数据或单位资料。
8. 从源码重建
构建需要 Rust 工具链、C 链接器;Python 运行时不需要它们。 本次验证的 Rust 为 Windows 1.99.0 / Linux 1.99.1。
cargo build --release --locked --offline
# Linux:将原生库放进 Python 包内,然后直接运行测试。
cp target/release/librustgzip_native.so python/rustgzip/
PYTHONPATH=python python3.4 tests/test_api.py
现代构建环境可运行 python setup.py bdist_wheel;较旧 Python 的构建工具已停止更新,
建议用现代 Python 构建 wheel,再在 Python 3.4 安装。wheel 使用 py3-none-平台 标签,
不伪装成纯 Python 或 manylinux 通用包。
tools/package_release.py --native <动态库路径> --platform linux_x86_64 可按白名单重打包。
不要直接压缩整个工作目录;build/target 中的编译缓存不是用户安装依赖。
9. 0.2.0 新增的缓冲区接口
`python import rustgzip
output = bytearray(32 * 1024 * 1024) # 由应用选择可信的容量上限,可以反复使用。 count = rustgzip.decompress_into(packed, output) result = memoryview(output)[:count] # 视图不复制完整结果;需要 bytes 时再显式转换。 `
容量不足、CRC/格式错误会抛出异常;失败后缓冲中的内容不可使用。 不要未经限制地根据 gzip 尾部 ISIZE 分配任意大内存,也不要在调用期间由其他线程访问 output。
源码学习和与 0.1.0 的逐项性能比较见 UPSTREAM-REVIEW.md。 本轮主要改善内存解压,文件 verify 没有本质提速,尚未实现普通单流多核解码。 0.2.0 的原生 ABI 为 2,0.3.0 为 3;0.3.1 / 0.4.0 为 4,后者新增可选并行扩展。 升级时替换整个包并重启 Python,不能混装 py 和动态库。
10. 0.3.0 的进一步优化
常见头部的内存解压直接使用同版本 zlib-rs 填充 Vec 剩余容量,复杂头部保留原解析器;串接文件跨 member 复用解码状态。API 用法不变,Python 3.4 仍受支持。
此次搜索、未采用的方案、性能波动及完整验证见 OPTIMIZATION-030.md。默认 verify 缓冲不变,普通单流多核解压仍未实现。
11. 0.3.1
修复刷新未到达文件、无效文本参数截断原文件、中断后的原生资源泄漏,以及缓冲扩容重试失败。 具体复现和修复见 REVIEW-031.md。原生 ABI 为 4,请替换完整包并重启使用它的 Python 进程。
Python 3.4 / 3.7 的运行回归各 82 项全部通过;Windows 通过 80 项,跳过 2 项 Linux 专用测试。
构建工具另有 7 项测试,请用现代 Python 运行 python tests/test_packaging.py。
性能 JSON 保留 0.3.0 的历史基线;本补丁以正确性为主,不宣称新增速度收益。
12. 0.4.0 可选并行实验
通过 from rustgzip.experimental import compress_parallel, prefetch 显式启用。
并行压缩保留 32 KiB 历史字典并合并 CRC,输出仍是单个标准 gzip member;
预取只把一个解码线程与调用方处理重叠,不是一个 gzip 流的多核解码。
原有 open / compress / verify 默认不变。
实验结果、使用示例、内存限制和失败处理见 PARALLEL-040.md。 Linux Python 3.4 / 3.7 各 100 项运行测试通过;新增 4 项 Rust 并发正确性测试。 并行压缩只支持至多 512 MiB 的内存输入,大文件仍使用现有文件流接口。
13. 0.5.0 并行路径继续优化
并行压缩改用调用内固定工作线程,按块完成情况继续领取任务;调用线程参与计算。
新增 rustgzip.experimental.compress_parallel_into,可以直接写入已有缓冲,减少完整结果
分配与复制。原有默认接口不变。性能收益、退化配置和示例见
OPTIMIZATION-050.md。当前运行测试为 106 项,Rust 并发测试为 5 项。
14. 0.5.2 审查修复
修复关闭中断时的原生句柄泄漏、预取意外 StopIteration 被当成 EOF、预取关闭中断 未完成清理,以及超限可变输入先复制再拒绝。高压缩率块及时收缩冗余容量,并加强 发布包身份和路径检查。复现、内存对照和限制见 REVIEW-051.md。 当前运行测试 115 项(主接口 85、实验接口 30),发布工具测试 10 项。
15. 开发中的普通 gzip 文件并行验证
当前整体架构、未解决瓶颈和下一步实施方向,优先阅读 架构瓶颈审计。它用三路径反事实和已知检查点 对照区分了符号成本、真实历史串行链与后端潜力;下面的局部实验成绩不能相加, 也不能当作已经完成普通 gzip 多核扩展。
审计后的第一步已实现独立符号内核:以任务输出为 LZ77 历史,结束时才构造尾窗, 并比较安全宽位读取。64 MiB 固定 CPU 对照中,未知历史日志从现有文件符号路径 约 177 提高到 329 MiB/s;这仅是第一阶段内核成绩,尚未接入工作池或 Python。 六项新增正确性测试、全部结果和接入条件见 符号内核原型报告。
源码内部已加入自主符号解码、候选扫描、有界文件工作池和按真实历史提交 CRC 的 验证原型,没有预建索引;巨大候选超出预算时可从可信位置跨窗口继续处理。 本机 Rust 默认 debug 构建回归为 176 项通过、3 项测量测试默认跳过。
另有显式 known-window-backend 构建:可信真实历史下的直接文件解码已接入
zlib-rs 底层后端。未知窗口 worker 已支持有界连续多块任务,在完整块边界且
尾窗口没有 Marker 时自动交接;当前该构建 debug 回归 186 项通过,全部实验开关
debug/release 各 206 项通过;各有 3 项测量测试默认跳过。
原生处理量区分候选工作和可信采用量。功能默认不启用,适配限制、32 KiB 误区见
P6 底层适配续篇,最新实现及本机开关
对照测速见 worker 交接报告。
现已补充共享顺序提交层,Rust 内部支持文件到自有内存及预分配缓冲的真实输出, 并有默认关闭的分段计时;依据诊断加入原生状态复用及减少提交复制。 最新测量、输出失败契约与接口路线见 输出与诊断报告。 这些不是已发布的 Python decompress_parallel 或 open_parallel。
后续已实现真实历史前缀、按压缩区间对齐的实验调度、u8 原生后缀及批量 match/stored 路径,并记录任务采用率、重解下界和丢弃分类。 32/64 MiB、1/2/4 worker 的实现和测量限制见 对齐调度优化报告。 进一步完成任务级尾窗恢复、原生缓冲复用、发布前一致性检查和 stored 长度前视; 最终较大样本的提速与剩余限制见 固定成本优化报告。
最新一轮分离物理读缓存与解析事务、借用原生后缀、汇总历史依赖、复用符号读取状态, 并提供显式 stored 专用路径。64 MiB 同轮对照中随机和日志改善,stored 接近顺序基线, 但无任务的重复数据路径仍有退化;完整结果与尚未解决的问题见 解码调优报告。
另有显式 intrablock-handoff 试验:重放原始块头恢复 Huffman 表,仅在完整 token
结束且窗口完全已知时切换,因此可在某些大压缩块的 EOB 之前进入原生后端。
它尚未作为默认路径:大块隔离测试明显获益,但完整调度样本未显示普遍收益。
默认 8 位 Huffman 表保留,长码不再重复解析已经查过的前缀;9/10 位表和回退统计
仅作为显式诊断选项。实现条件、对照测量及限制见
结构优化报告。
进一步定位并修复无任务路径的批次分配、直接块状态重建和重复文件状态检查, 已证明没有可用网格的 Aligned 文件不再创建空闲线程。重复数据的旧退化明显收敛, 但日志的符号处理与顺序提交仍使并行路径慢于顺序基线;控制实验、正确性边界及 真实历史反馈的后续方案见 退化定位报告。
现已加入默认关闭的 history-feedback 实验:向运行中的推测任务提供精确原始
位起点的真实历史,解析当前窗口后尝试块内原生交接,不等待字典,旧 Marker
前缀及最终 CRC 仍完整校验。64 MiB 日志单 worker 能命中反馈,四 worker
尚未命中,整体仍慢于顺序基线;不能把该机制已实现等同于日志提速已完成。
安全边界、命中统计和开关对照见
历史反馈实验报告。
后续显式 unknown-prefix-yield 实验在未知引用长期存在、符号前缀达到 256 KiB
后的完整块边界提前交付,由真实历史任务接续,不让 worker 原地等待字典。
64 MiB 日志四 worker 同轮由约 465 提升至 624 MiB/s,但仍低于顺序约 922 MiB/s,
2→4 worker 扩展也仍有限。它不是巨大 Huffman 块中途暂停功能,仍默认关闭;
正确性、失败回收和采用量见 前缀交付实验报告。
另有显式 direct-native-output 实验,使用已初始化 Vec 尾部直接接收 worker 原生
输出,减少 scratch→结果的复制。64/128 MiB 对照没有显示稳定的四线程收益,
因此仍默认关闭,不替换既有路径;初始化、失败回滚和复测结果见
原生直接输出实验报告。
时间线进一步确认日志已知历史任务基本串行:原生处理占比高不等于任务可并发。
显式 coordinator-native 在当前 member 实际采用 Marker 前缀后,让可信后继
直接由协调器连续推进,保留前方并行推测,并按需读取 stored 等价头信息。
128 MiB 同源码七轮对照中日志四 worker 约 624→667 MiB/s,单 worker 约
510→703 MiB/s;仍低于顺序基线,不能称四核扩展完成。确切主因、失败方案、
策略重置和最终对照见 关键路径定位报告。
块内交接现另有显式 distance-bounded-handoff:移除窗口已经真实时的块内 32 KiB
输出门槛;仅对终块,还可根据距离树上界使用已知短尾字典,保留更早 Marker。
单未知大动态块同轮约 1799→2174 MiB/s,符号前缀 32768→2 字节。普通日志仍
没有块内重放机会,不能套用该提升;终块限制、配额和完整管线实验证据见
距离约束交接报告。
新增显式 spare-native-output 实验:worker 原生输出直接写 Vec 备用容量,
省掉尾部预清零,只发布实际写入的字节;失败回滚和终止规则继续生效。
普通数据有收益,隔离高压缩率样本也出现退化,按膨胀率自动回退的方案已因
误判撤回,因此继续默认关闭。最终三路测速、安全边界及测试见
备用容量输出报告。
另有默认关闭的 reuse-native-history,在协调器导出块尾字典时复用已消费的
历史 Vec,避免逐块重新分配和清零。专项测试确认短/空窗口不会带出旧字节,
但两轮 128 MiB 对照未显示稳定吞吐收益,不能当成已完成的提速。
实现、安全边界和全部结果见 历史缓冲复用报告。
继续加入默认关闭的 lazy-native-history 与 quiet-idle-workers:真实历史只在
候选验证/反馈等确实需要时导出;队列为空时不广播任务通知,完成/取消等通知保留。
128 MiB 日志窗口导出由 1417 次降到 14 次;在按需历史开启后再省空队列通知,
四 worker 两轮约改善 1.9%、8.3%,但单 worker 部分配置仍有退化,仍慢于顺序。
实现、专项测试、通知计数和完整开关对照见
按需历史与通知报告。
尚未提供 Python 调用入口,也没有 UOS 实机结论。 本机已有端到端开关对照; 随机 Base64 样本经调参已实测超过同轮顺序基线;这不代表 stored、日志或所有 gzip 都能超过顺序路径,也不代表已经完成 UOS 上的多核验收。 当前发布包及上文的公共 API 仍保持 0.5.2 行为。实现范围、预算、测试和待完成事项见 文件工作池报告。
Metadata
Release files for rustgzip 0.5.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| rustgzip-0.5.2.tar.gz | 832.8 kB | Without provenance | Details |
Built distributions (wheels)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rustgzip-0.5.2-py3-none-win_amd64.whl | Python 3 | none | Windows x86-64 | Details |
| rustgzip-0.5.2-py3-none-manylinux_2_28_x86_64.whl | Python 3 | none | Linux glibc 2.28+ x86-64 | Details |
Total release size: 1.8 MB
Release files / rustgzip-0.5.2.tar.gz
| Download URL | rustgzip-0.5.2.tar.gz |
|---|---|
| Size | 832.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
7eb195f00d9e9339e39815b876bc617607d2b6e63705e75fb2279c5e5caf634f
|
|
BLAKE2b-256 checksum How to use checksums |
4d75725dfb7c1bc5bbd76c08444497db7f6150730a2f747ec67271d8965c062b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / rustgzip-0.5.2-py3-none-win_amd64.whl
| Download URL | rustgzip-0.5.2-py3-none-win_amd64.whl |
|---|---|
| Size | 429.0 kB |
| Tags | Python 3 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
d43c326882a8d4acdc5db9bedd10e49f312ee33cadecf4f01e573d6d4eab2eef
|
|
BLAKE2b-256 checksum How to use checksums |
be369707b0512d3d08294ff73fe2742adff6cdda9254b41cccf3ee3789b78158
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Release files / rustgzip-0.5.2-py3-none-manylinux_2_28_x86_64.whl
| Download URL | rustgzip-0.5.2-py3-none-manylinux_2_28_x86_64.whl |
|---|---|
| Size | 543.4 kB |
| Tags | Linux glibc 2.28+ x86-64 Python 3 |
|
SHA-256 checksum How to use checksums |
431c4543cfc990f8b441ebb1f295c6fa9e7d6cedc6d0ef926c11b1919d8d131e
|
|
BLAKE2b-256 checksum How to use checksums |
fae9a73ca0ff728be9a79e7072a28db95141b69961f964354682356822b0ed70
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.14.0
|
Security for rustgzip 0.5.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.