Hacker News 中文摘要

RSS订阅

bzip3 压缩工具 -- bzip3

BZip2(BZip2)的一款更好更快更强的精神继承者 BZip3(BZip3),拥有更高压缩比与更佳性能,其特性归功于 order-0 上下文混合熵编码器、利用后缀数组的快速 Burrows-Wheeler 变换代码,以及基于 LZ77 风格字符串匹配与 PPM 风格上下文建模且带 Lempel Ziv+ 预测通道的 RLE。如同祖先,该工具擅长压缩文本或代码。

正文

BZip2 更好、更快、更强的精神继承者。得益于 order-0 上下文混合熵编码器、利用后缀数组的快速 Burrows-Wheeler 变换,以及基于 LZ77 式字符串匹配和 PPM 式上下文建模的 RLE 与 Lempel Ziv+预测,它拥有更高压缩比和更好性能。如同前辈,BZip3 擅长压缩文本或代码。

安装

若使用 git 克隆(源码包不需要),先运行 ./bootstrap.sh。通用步骤:执行 ./configure,make,sudo make install。也可通过系统包管理器安装。

打包状态

在 macOS 上可用 Homebrew 轻松安装:brew install bzip3。

Perl 源码基准测试

先下载所有已发布的 Perl5 版本并解压,得到 262 个 tar 文件。将它们合并为单个 all.tar 并用多种压缩器测试。

使用各压缩器的耗时与内存:xz -T16 -9 -k 总耗时 12:09.24,内存 14658M;bzip2 -9 -k 17:16.64,8M;bzip3 -e -b 256 -j 12 7:10.10,18301M;bzip3 -e -b 511 -j 4 7:08.65,12178M;zstd -T12 -16 6:35.62,687M。

压缩后大小如下:

| 方法 | 压缩大小(字节) | | --- | --- | | LZMA (xz) | 2,056,645,240 | | bzip2 | 3,441,163,911 | | bzip3 -b 256 | 1,001,957,587 | | bzip3 -b 511 | 546,456,978 | | Zstandard | 3,076,143,660 |

解压时间(WD Blue HDD):

| 方法 | 解压时间 | | --- | --- | | LZMA (xz) | 4分40秒 | | bzip2 | 9分22秒 | | bzip3 (并行) | 4分06秒 | | Zstandard | 3分51秒 |

接着用 lrzip 对原 tar 做长距去重:lrzip -n 耗时 11:28.00,lrzip --lzma 11:44.83,lrzip -b 10:34.10。再用 bzip3 -e -b 256 -j 2 压缩生成的 none.tar.lrz,耗时 22.411,内存 2751M。

结果:

| 方法 | 压缩大小(字节) | | --- | --- | | lrzip + bzip3 | 60,672,608 | | lrzip + lzma | 64,774,202 | | lrzip + bzip2 | 75,685,065 |

更多与 Turbo-Range-Coder 和 BSC 的对比见 powturbo 的基准。

免责声明

作者不对因使用本程序/库导致的任何数据丢失负责,无论原因。

压缩文件即假设能解压还原。虽经精心设计和广泛测试,但算法复杂,低概率特殊情形可能遗留 bug。除非愿意接受数据可能无法恢复的小风险,否则勿用此程序压缩数据。程序并非不可靠,实际上作者希望相反。Bzip3/libbz3 已谨慎构建和测试。

Bzip3 性能严重依赖编译器。x64 Linux clang13 构建每线程压缩可达 17MiB/s,解压 23MiB/s。Windows 和 32 位构建可能明显更慢。

已测试架构:

  • x86
  • x86_64
  • armv6
  • armv7
  • aarch64
  • ppc64le
  • mips
  • mips64
  • sparc
  • s390x

语料库基准

基准测试可视化

更多结果见 etc/BENCHMARKS.md。

许可

整体代码库版权 2022-2023 Kamila Szewczyk,LGPL 许可。BWT(libsais)和 LZP 代码来自 Ilya Grebnov,Apache 2.0。bzip3 整体仅以 LGPLv3 授权,非双许可。

感谢

  • Ilya Grebnov 提供 libsais 库用于 BWT 构造和 LZP 编码器参考。
  • Caleb Maclennan 配置 autotools 作为打包友好的构建系统。
  • Ilya Muravyov 提供公有领域 BWT 后编码器,其衍生用于本项目。

评论

开场讨论承接了之前两轮对 bzip3 的报道,评论区迅速分裂成两派:多数人认为文章里的基准测试明显“作弊”、参数挑得太巧,并用实测数据反杀;少数人则认可压缩率的绝对数值惊艳,但无奈被项目维护状态和兼容性劝退。讨论没有停留在“压得小不小”,而是深挖到“比法公不公平”、BWT 算法特性与大型语料库的适配这类技术细节。

基准测试窗口参数不公,用 zstd 长距离模式反超 bzip3

  • 这是全场最核心的反驳:bzip3 块大小设成 512MB,但 zstd 窗口却用默认值(高等级下约 8MB)。而测试语料是把所有版本的 Perl 源码拼接在一起,等于故意让 zstd 看不到完整重复文件,只能在小窗口里打转。
  • 有评论直接用实测数据证伪:把 zstd 的 --long=29 窗口拉到与 bzip3 匹配后,压缩结果直接缩小 15 倍左右,而且比 bzip3 同结果还小两倍以上,CPU 时间也砍了一半。更别提语料里那种超长重复文本本就是 BWT 压缩器的天然主场。引用: > 如果对齐两者的窗口,zstd 不仅压得更小,而且更快,因为长匹配能更早被找到,需要处理的工作反而变少了(@ot)
  • 还有评论精准补刀:文章拿 bzip3 的并行解压去比 bzip2 的串行解压,显然是不公平的,要比较也该用 pbzip2 才对。并推测作者可能压根没意识到自己窗口设得太小,导致单个版本 tar 包内的重复都抓不到。

项目停更、构建失败,口号式宣传让人不敢用

  • 有人从项目健康度入手吐槽:最新发布距今一年多,最近一次提交也在两个月前,而且 CI 构建已经挂了。这种状态下的“更强”声明根本没有说服力——它究竟强在哪?比 bzip2 强?比 zstd 强?还是只在使用特殊参数时强?
  • 还有人揪出 README 里那句“除非你能承受数据可能不可恢复的风险,否则不要拿它压缩任何数据”,觉得这简直是劝退警告。既然老牌工具像 7zip 都没贴这种免责声明,凭什么要用户去赌一个停更项目里的极小概率 bug?引用: > 无论爱好者还是企业,看到这句“数据可能无法找回”都会问一句:那我为什么还要用它?(@sergiotapia)

谁该为“压缩率”放弃生态兼容?这让人 FOMO 又不甘心

  • 有用户分享处理 JSONL 存档的经历:LZMA 压缩率比 gzip 和 bzip2 好太多,能省下实打实的归档成本,但 DuckDB 这些常用工具只透明支持 gzip,bzip2 得靠扩展,LZMA 和 bzip3 根本没有现成接口。
  • 最终只能为了软件兼容性选择 gzip,接受最差的压缩结果。看完 bzip3 的测试数字确实是“怕错过”,但冷静下来发现生态支持不解决,压缩率只能是个观赏性数字。这其实暗示了压缩算法竞争的真正瓶颈不在算法本身,而是周围工具链愿不愿意跟进。

有价值的补充

  • 比起无休止的基准拉锯,有人提议拿 bzip3 当“软件形式化验证 + AI”的试验场:作者自己都承认代码里有大量低概率触发的特殊分支,没法靠人肉排除 bug,这正是机器验证能发挥价值的地方。
  • 有个反套路的思路:与其在各种语料上做宣称,不如直接去对比 bzip3 自己发布的 GitHub Release 文件用什么参数压缩的,以及它那几个压缩包是否比别的压缩器更适合自己——即用自家 CI 配置当真实的“吃自己的狗粮”测试。
  • 评论区带出一个冷知识:bzip3 用的 Burrows-Wheeler 变换在以前那篇报道里被作者本人解释得很透彻,它对付超长重复文本的能力几乎是刻在算法基因里的,这决定了拿它测“全版本源码拼接”这种语料本身就有点讨巧。