架构优化-压缩
作者:互联网
引入
压缩的本质上就是牺牲精度或者cpu计算换空间的一种做法,所以通常情况下来说架构设计的过程中都会更加偏向针对热点优化解决,『压缩』的引入就是最常用的手法之一。
原理
压缩的基本原理就是将原来数据文件的编码方式通过找寻期中的编码排序的规律,
分类
压缩从精度损失来看基本上分成两种: 无损压缩 和 有损压缩两种:
-
有损压缩:一般来说有损压缩的压缩比比较大,是牺牲数据精度或者次要数据来换取更大压缩比的算。
-
无损压缩:无损压缩主要是使用两种编码思路来进行数据压缩,熵编码和字典编码。
熵编码
根据信息概率分布,来对所有信息进行重新编码。核心在于提高符号的信息熵。
- 霍夫曼编码:根据数据出现的频率构建霍夫曼数,频率出现高的用的编码符号短,最终使用霍夫曼符号代替原始符号。
- 算数编码 和区间编码也是数据熵编码的范畴,解释比较复杂,这里不过多赘述了。
字典编码
根据信息中重复出现的部分作为字典,然后通过映射关系代替重复出现的部分。
- LZ77与LZ78:最经典的字典编码,很多算法都是完全基于这种算法或者说这种算法的变体实现的。
- LZ77:通过滑动窗口实现,用前面出现过的字符串通过字典映射,代替后面重复出现的字符串。
- LZ78: 通过预先扫描机制来进行实现。
- LZSS: 基于LZ77的变种优化,后验替换是否真的减小了文件等一些优化。
- LZW:基于LZ78的衍生,优化字典编码存储,在GIF中使用。
常见压缩算法
-
DEFLATE: 先用LZ77(或 LZSS)算法预处理,然后用霍夫曼编码对压缩后的 literal、length、distance 编码优化,如今最流行的通用压缩算法之一
-
bzip2: 涉及多种算法,主要流程包括先使用 Run-length Encoding 游程编码对原始数据进行处理,然后通过 Burrows-Wheeler Transform 转换(可逆的处理一段输入数据使得相同字符连续出现的次数最大化),再用 Move-to-front transform 转换,然后再次使用Run-length Encoding游程编码处理,接下来还会进行霍夫曼编码以及一系列相关处理,较为复杂,速率劣于DEFLATE但压缩率更高
-
LZMA:实现了LZ77修改版以位(bit)而非字节(byte)为单元级别的操作,并通过马可夫链实现字典索引,速率和压缩率优于bzip2,另有多线程优化的版本LZMA2
-
Brotli: 基于LZ77算法的一个现代变体,使用了霍夫曼编码和二阶上下文建模,使用了预定义的120千字节字典包含超过13000个常用单词、短语和其他子字符串,预定义的算法可以提升较小文件的压缩密度。总体速率接近于DEFLATE且压缩率接近于LZMA
应用实践
刚刚说了那么多压缩的原理,但是可能实际生活过程中我们最需要的是,有那些压缩算法,应该怎么用,如何筛选
非数值压缩
速度优先
以Snappy为代表的压缩算法,包括Snappy,LZ4,LZF、QuickLZ等为代表的快速压缩算法。
snappy
- 思路:LZ77变种,2011年开源
- 目标:最高压缩速度、合理压缩率
- 代码:https://github.com/google/snappy
压缩率优先
- gzip 和 pigz(多线程 gzip)的实现基于 zip 库,实现了 ZIP 算法。
- 7-Zip 主要基于 LZMA 和 LZMA2 算法实现的软件,有着很高的压缩比,压缩和解压缩速度比较慢
前缀后缀
针对某些特殊的字符串,存在大量相同的前缀和后缀的可以考虑使用,以Trie树或者FST为典型使用的数据结构
- Tire树:tire-tree,确定无环有限状态接收机(Deterministric acyclic finite state acceptor, FSA)
- FST: Finite State Transducers(有限状态传感器)
常见无损压缩对比
数值压缩算法
由于数值压缩则包含精度的问题,数值压缩一般来说就是对一组数据int,或者float 或者其他类型的数据做压缩,一般来说包含有损压缩或者无损压缩两方面。
变长压缩
以varint 和 zigzag 为代表的无损数值要所算法,例如protobuf 和 thrift 都是结合两种来实现的,数字中通常都是小整数负数,没必要所有的数字都使用4字节或者8字节来匹配。
varint
varint可以压缩较小的正数,但是对于负数varint反而更浪费空间。
zigzag
zigzag编码可以处理负数,使负数也可以使用varint编码压缩。
差分压缩
(英语:Delta encoding),又称增量编码,是指在序列式资料之间以数据差异形式存储或发送资料的方式(相对于存储发送完整文件的方式)。差分编码应用广泛,如需要查看文件的历史更改记录(版本控制、git等)、Windows中的远程差分压缩、在线备份等场景均用到了差分编码。
精度损失
将原本的float 以fp16进行数据压缩。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TGyU99GD-1620125056630)(evernotecid://F6D43139-438F-4E0C-A655-A59565962559/appyinxiangcom/13263551/ENResource/p378)]
详细信息可以参考下面
https://blog.csdn.net/ljyss9/article/details/106742877
总结
总体上来讲,压缩就是一种服务优化的手段,没有任何一种方法是完美的,本文中提到的所有的压缩算法,没有针对图像、视频等领域相关的算法。如果涉及这个领域的有损压缩又会涉及到:
色彩空间、色度抽样、DTC、分形压缩等基于图像特点的模型,日常工作中选择任何算法都是成本收益的折衷,需要根据实际使用场景和所要达成的目标而定。
标签:编码,架构,压缩算法,压缩,算法,LZ77,优化,字典 来源: https://blog.csdn.net/qq_42828391/article/details/116403524