Python使用zstd压缩算法
Facebook的Zstandard(简称zstd)压缩算法逐渐流行,它有以下特点:
1,压缩、解压速度快。
这张图的横轴是压缩率,纵轴是压缩速度。
在高压缩等级时,压缩率接近LZMA;在低压缩等级时,速度接近LZ4。(zstd和LZ4的作者是同一个人)在各种情况下,比常用的zlib快,可以考虑替代zlib。
下图出自这个网页,里面还有一些比较图表。
zstd还多线程压缩,可以充分利用多核CPU,让压缩速度提高数倍。
但不支持多线程解压,不过解压速度已经非常快了,通常比SSD快。
2,如果使用预先训练的zstd字典,对于几KB的小数据,可以大大提高压缩率。
要压缩的数据越小,就越难压缩,这是所有压缩算法都有的问题,原因是压缩算法从之前的数据中学习如何压缩之后的数据,但对于小数据,没有“之前”可以参考。
为了解决这一问题,zstd提供了一种训练模式,针对特定的数据类型调整算法。训练是通过提供一些样本(每个样本一个文件)来实现的,训练的结果存储在一个名为“字典”的文件中,在压缩和解压缩之前必须加载该文件,使用这个字典,可以大大提高小数据的压缩比。
下图是压缩1万条1KB的数据,在使用字典时,压缩率、压缩速度、解压速度大大提高。
3,帧(frame)和块(block)让使用更灵活,适用各种场景。
zstd数据由1个或多个独立的帧(frame)组成,解压后的多帧数据 等于 每帧解压后再相接。
每帧完全独立,包括一个帧头,以及一套解压参数。
zlib和LZMA也支持多帧的特性。
每帧包括1个或多个块(block),块的最大尺寸是(3字节 128KB),具体取决于帧头里定义的参数。
和完全独立的帧不同,在解压时块依赖前面的块、不依赖后面的块,块可以被全部解压,所以块可以用于通讯场景。
zlib也有类似块的特性。
pyzstd模块
用了6个月时间,写了一个pyzstd模块,它的API和Python标准库里的bz2/lzma/zlib模块相似。
https://pypi.org/project/pyzstd/
PyPI上还有两个zstd模块:
zstd:它太简单了,只提供了很少的基本功能。
zstandard:提供了丰富的API,但是API风格和Python标准库的bz2/lzma/zlib不同,可以看看。