zoukankan      html  css  js  c++  java
  • Python使用zstd压缩算法

    Facebook的Zstandard(简称zstd)压缩算法逐渐流行,它有以下特点:

    1,压缩、解压速度快。

    下图的横轴是压缩比,纵轴是压缩速度

    • 高压缩等级时,压缩比接近lzma。(但解压更快)
    • 低压缩等级时,速度接近lz4。(zstd和lz4的作者是同一个人)

    在各种情况下,性能比zlib好,可以考虑替代zlib。

    图片出自这个网页,里面还有一些比较图表。

    zstd自带多线程压缩,充分利用多核CPU,让压缩速度提升数倍。
    原理是把数据分成多份,并行压缩出一个单帧zstd数据,可以设置 每份的大小、重叠部分的大小。

    但不支持多线程解压,不过解压速度已经很快了,通常比SSD快。解压速度可以看zstd网站首页的表格。

    2,如果使用预先训练的zstd字典,对于几KB的小数据,可以大大提高压缩比。

    要压缩的数据越小,就越难压缩,这是所有压缩算法都有的问题,原因是压缩算法从之前的数据中学习如何压缩之后的数据,但对于小数据,没有“之前”可以参考。

    为了解决这一问题,zstd提供了训练模式,针对特定的数据类型训练字典。训练是通过提供一些样本(每个样本一个文件)来实现的,训练的结果(字典)存储在一个文件中,在压缩和解压之前必须加载该文件。

    使用字典可以大大提高几KB的小数据的压缩比,对于1KB以下的小数据有最好效果。

    下图是压缩1万条大约1KB的数据,在使用字典时,压缩比、压缩速度、解压速度大大提高。



    注意:

    • 如果丢失了字典,就不能解压相应的数据。
    • 对于几MB的大数据,字典的效果微不足道。

    除了用样本训练字典,还可以手工编写一个更高效的字典,然后用一些样本完成(finalize)这个字典。
    比如把JSON文件中的共有部分精心挑选出来,写到一个文件里,然后用一些JSON样本完成(finalize)这个字典,这样得到的字典可能用样本训练的字典更高效。

    3,帧(frame)和块(block)让使用更灵活,适合各种场景。

    zstd数据由1个或多个独立的帧(frame)组成,解压后的多帧数据 等于 每帧解压后再相接
    每帧完全独立,包括一个帧头,以及一套解压参数。
    zlib和lzma也有这样的多帧特性。

    每帧包括1个或多个块(block),块的尺寸上限是3字节块头+128KB,块的实际最大尺寸取决于帧头里定义的参数。
    和完全独立的帧不同,在解压时,块依赖之前的块、不依赖之后的块,完整的块可以被全部解压。所以flush块可以用于通讯场景,接收方可以立刻解压。
    zlib也有类似块的特性。

    Python使用zstd压缩算法

    用了几个月时间,写了一个pyzstd模块,它的API和Python标准库中的bz2/lzma/zlib模块相似。
    PyPI页面:https://pypi.org/project/pyzstd/
    文档(英文):https://pyzstd.readthedocs.io/en/latest/
    GitHub页面:https://github.com/animalize/pyzstd

    PyPI上还有两个zstd模块:

    zstd:它太简单了,只提供很少的基本功能。
    zstandard:提供了丰富的API,但是API风格和Python标准库的bz2/lzma/zlib不同。

    zstd杂谈

    1, 上面提到:在高压缩等级时,压缩比接近lzma;在低压缩等级时,速度接近lz4。
    可能有人好奇这是怎么做到的,这是因为zstd内部提供了几套压缩代码,适用于不同的压缩等级。(但格式是相同的)
    缺点就是二进制代码很大,比较几种算法的DLL文件,zlib大约110KB,lzma大约150KB,bz2大约80KB,zstd达450KB。

    不过zstd的二进制代码可以裁剪,以下三种功能可以按需留取:压缩、解压、训练字典。压缩中的多线程压缩也是可裁剪的。
    比如一个APP只需要解压zstd数据,可以只编译解压代码,编译后的解压可执行代码仅40~70KB。

    2, zstd的核心代码考虑了乱序执行,v1.5支持SIMD(SSE2或Neon),感觉比较“现代”。

    3, zstd的C代码大量使用常量传播(constant propagation),更智能的编译器会有更好的内联优化。
    似乎MSVC在这方面较弱,见此文,文中说MSVC会进行改进。目前(2021年1月)MSVC编译的比GCC编译的慢6%~10%。
    zstd代码可能也会针对MSVC做些调整。

    4, 近来一些库重写了DEFLATE算法,比如libdeflateISA-L,可以将gzip的压缩速度、解压速度提升到zstd的级别。

    也许zstd不会替代lzma,lzma能有更高的压缩比。
    相比lzma,zstd有更快的解压速度,见Linux内核Arch Linux的报道。

    5, 最后贴一张2019年11月做的性能比较
    zstd还处于活跃的开发中(现在是2021年),每个版本可能会有少量性能提升。

    zlib/bz2/lzma,这些库有的已经很久没有实质更新,有的更新缓慢(只有一个人在开发)。
    zstd小组好像有4个员工,还有一些贡献者参与,很活跃。
    活跃的负面效果是可能引入少量边缘性的bug,可以看更新日志了解一下。

  • 相关阅读:
    Elasticsearch 从入门到学会之五(索引API-索引属性)
    jenkins 如何发布用java -jar来启动的java项目
    k8s从入门到精通-Pod定义详解
    Docker从入门到精通<9>-docker配置文件以及重启策略
    Docker从入门到精通<8>-docker-compose任务编排
    如何选择Containerd和docker
    Docker从入门到精通-企业级私有仓库harbor
    Docker从入门到精通<7>-docker存储驱动选择
    Docker从入门到精通<6>-使用Dockerfile构建镜像
    Docker从入门到精通<5>-数据持久化
  • 原文地址:https://www.cnblogs.com/animalize/p/14290701.html
Copyright © 2011-2022 走看看