LZ4 (Extremely Fast Compression algorithm)

项目:http://code.google.com/p/lz4/

作者:Yann Collet

本文作者:zhangskd @ csdn blog

简介

LZ4 is a very fast lossless compression algorithm, providing compression speed at 400MB/s per core,

scalable with multi-cores CPU. It also features an extremely fast decoder, with speed in multiple GB/s per core,

typically reaching RAM speed limits on multi-core systems.

A high compression derivative, called LZ4_HC, is also provided. It trades CPU time for compression ratio.

(1) 横向对比

Quick comparison: single thread, Core i5-3340M @2.7GHz, using the Open-Source Benchmark by m^2 (v0.14.2)

compiled with GCC v4.6.1 on Linux Ubuntu 64-bits v11.10, using the Silesia Corpus.

对比当前流行的压缩工具,可以看到LZ4具有最快的压缩和解压速度,尽管压缩比一般。

QuickLZ官网:http://www.quicklz.com/

QuickLZ is the world's fastest compression library, reaching 308MB/s per core.

QuickLZ自称是世界上最快的压缩算法,然而我们看到它和LZ4还是有差距的,特别是解压速度。

snappy项目:https://code.google.com/p/snappy/

snappy is developed by Google based on ideas from LZ77 and open-sourced in 2011.

It was designed to be very fast and stable, but not to achieve a high compression ratio.

Compression speed is 250MB/s and decompression speed is 500MB/s using a single threaded,

64-bit core i7 processor. The compression ratio is 20-100% lower than gzip.

snappy追求的是速度,压缩比并不高。

(2) 纵向对比

LZ4能很好的支持多线程环境,获得更高的压缩和解压速度。

(3) 技术背景

多媒体技术 -> 无损压缩 -> 词典编码 -> LZ77算法 -> LZ4

词典编码(Dictionary Encoding),根据的是数据本身包含有重复代码序列这个特性。

主要分为两类:

1. 查找正在压缩的字符序列是否在前面输入数据中出现过,如果是,则用指向早期出现过的字符串的“指针”替代

重复的字符串。这里的“词典”是指以前处理过的数据。(LZ77、LZSS)。

2. 从输入的数据中创建一个“短语词典”,编码数据过程中当遇到已经在词典中出现过的“短语”时,编码器就输

出这个词典中的短语的“索引号”,而不是短语本身。(LZ78、LZW)

(4) 其它格式

以下是一些常用的压缩格式。

1. zip

zlib库,可通过包含zlib.h使用。

zip原名为Deflate,仅支持一个LZ77的变种算法Deflate。

zip/unzip,后缀为.zip。zip也是Windows下常见的压缩格式。

2. gzip

gzip/gunzip是GNU程序,后缀为.gz。Web也常用GZIP压缩技术。

首先使用LZ77算法进行压缩,对结果再使用huffman编码进行压缩。

tar中用-z来调用:

tar -czf pic.tar.gz *.jpg

tar -xzf pic.tar.gz

3. bzip2

bzip2/bunzip2,后缀为.bz2。

相比于gzip,压缩比更高,压缩效果比传统的LZ77/LZ78更好,但压缩速度较慢。

首先使用Burrows-Wheeler变换(BWT,块排序文本压缩),然后使用哈夫曼编码进行压缩。

tar中使用-j来调用:

tar -cjf pic.tar.bz2 *.jpg

tar -xjf pic.tar.bz2

4. compress

compress/uncompress,后缀为.Z,现在已经不再流行了。

使用LZ78算法的变种LZW。

tar中使用-Z来调用。

6. rar

rar/unrar,后缀为.rar。

rar格式较zip格式的压缩比高。

注意RAR非免费,是Windows下常见压缩格式,也有RAR for Linux。

rar a pic *.jpg // pic.rar

rar e pic.rar // pic

7. 7z

7-Zip,后缀为.7z。

和rar、zip一样,7z也是Windows下常见的压缩格式。

使用改良与优化后的LZ77算法LZMA、LZMA2,压缩比高于zip。

8. xz

xz,后缀为.xz。

如果说LZ4是压缩速度之王,xz则是压缩比之王。

一般来说,用xz压缩后的文件,能比用gzip压缩的小30%,比用bzip2压缩的小15%。

主要使用LZMA2压缩算法。

tar不支持xz格式,xz / xz -d。

LZ77

我们看到很多压缩格式都是基于LZ77的,所以先来了解下LZ77算法,这里引用了较多的网上资料:)

1977年,Jacob Ziv和Abraham Lempel描述了一种基于滑动窗口缓存的技术,该缓存用于保存最近刚刚处理的文本。

LZ77编码的核心是查找从前向缓冲器开始的最长的匹配串。

压缩算法使用了两个缓存:

1. 滑动历史缓存,包含了前面处理过的N个源字符。

2. 前向缓存,包含了将要处理的下面L个字符。

压缩过程

算法尝试将前向缓存开始的两个或多个字符与滑动历史缓存中的字符串相匹配。

如果没有发现匹配,前向缓存的第一个字符作为9bit的字符输出并且移入滑动窗口,滑动窗口中最久的字符被移除。

如果找到匹配,算法继续扫描以找到最长的匹配。然后匹配字符串作为三元组输出(选项、指针和长度)。对于K个字符

的字符串,滑动窗口中最久的K个字符被移出,并且被编码的K个字符被移入窗口。

更具体来说:

1. 从当前压缩位置开始,查看未编码的数据,并试图在滑动窗口中找出最长的匹配字符串,如果找到,则进行步骤2,否则进行步骤3。

2. 输出三元符号组(off, len, c)。其中off为窗口中匹配字符串相对窗口边界的偏移,len为可匹配的长度,c为下一个字符。

然后将窗口向后滑动len + 1个字符,继续步骤1。

3. 输出三元符合组(0, 0, c)。其中c为下一个字符。然后将窗口向后滑动len + 1个字符,继续步骤1。

实例

假设窗口大小为10个字符,我们刚编码过的字符(滑动窗口)是:abcdbbccaa,即将编码的字符(前向缓存)是:abaeaaabaee。

1. 和编码字符匹配的最长串为ab,下一个字符为a,输出三元组(0, 2, a)。

窗口向后滑动3个字符为:dbbccaaaba,前向缓存为:eaaabaee。

2. 字符e在窗口中无匹配,输出三元组(0, 0, e),窗口向后滑动1个字符为:bbccaaabae,前向缓存为:aaabaee。

3. 前向缓存的最长匹配串为aaabae,下一个字符为e,输出三元组(4, 6, e),完成编码。

解压过程

解压算法必须保存解压输出的最后N个字符(滑动窗口)。

当碰到编码字符串时,使用指针和长度字段,将编码替换成实际的正文字符串。

评价

算法使用了有限的窗口在以前的文本中查找匹配,对于相对于窗口大小来说非常长的文本块,很多可能的匹配就会被丢掉。

窗口大小可以增加,但这会带来两个损失:

1. 算法的处理时间会增加,因为它必须为滑动窗口的每个位置进行一次与前向缓存的字符串匹配的工作。

2. 指针字段必须更长,以允许更长的跳转。

在多数情况下,lz77拥有较高的压缩效率。而在待压缩文件中绝大多数是些超长匹配,并且相同的超长匹配高频率地反复

出现时,lzw更具优势。GIF就是采用了lzw算法来压缩背景单一、图形简单的图片。zip是用来压缩通用文件的,这就是它

采用对大多数文件有更高压缩率的lz77算法的原因。

优化

精心设计三元组(off, len, c)中每个分量的表示方法,才能达到较好的效果。

(1) off

off为窗口内的偏移,通常的经验是,偏移接近窗口尾部的情况要多于接近窗口头部的情况,这是因为字符串在与其接近的

位置容易找到匹配串,但对于普通的窗口大小(如4096字节)来说,偏移值基本还是均匀分布的,我们完全可以用固定的位

数来表示它。

(2) len

len为字符串长度,它在大多数时候不会太大,少数情况下才会发生大字符串的匹配。显然可以使用一种变长编码方式来表

示该长度值。要输出变长的编码,该编码必须满足前缀码的条件。Huffman编码可以用于此处,但不是最好的选择。

Golomb编码应用比较广泛,对于较小的数用较短的编码,对较大的数用较大的编码表示。

(3) c

c为前向缓存中的不匹配字符。直接用8个二进制位编码。

(4) 输出格式

LZ77的原始算法采用三元组输出每一个匹配串及其后续字符,即使没有匹配,仍需要输出一个len=0的三元组来表示单个字符。

实验表明,这种方式对于某些特殊情况(例如同一字符不断重复的情形)有着较好的适应能力。

对一般数据,有一种更有效的输出方式。

将每一个输出分成匹配串和单个字符两种类型,并首先输出一个二进制位对其加以区分。例如,输出0表示下面是一个匹配串,

输出1表示下面是一个单个字符。之后,如果要输出的是单个字符,我们直接输出该字符的字节值,需要8个二进制位。

也就是说,输出一个单个的字符共需要9个二进制位。

如果要输出的是匹配串,则输出off和len。off可以用定长编码,也可以用变长前缀码。len用变长前缀码。有时候我们可以对匹配

长度加以限制,例如,限制最少匹配3个字符。因为对于2个字符的匹配串,我们使用匹配串的输出方式不一定比我们直接输出2

个单个字符(共需18位)节省空间。

这种输出方式的优点是:输出单个字符的时候比较节省空间。另外,因为不强求每次都外带一个后续字符,可以适应一些较长

匹配的情况。

(5) 查找匹配串

在滑动窗口中查找最长的匹配串,是LZ77算法中的核心问题,关系着空间和时间复杂度。

golomb

哥伦布编码。主要针对整数进行编码,对较小的数用较短的编码,对较大的数用较大的编码表示。

假设x为要进行编码的整数,当x趋于较小的取值时候,此时的Golomb编码较短,可以有效的节省空间。

压缩算法:

1. 选定参数m,b = 2^m,注意m是要在压缩前指定的。

2. q = <int> ((x - 1) / b),<int>表示取整。

3. r = x - qb - 1,所以x = qb + r + 1。(注意这个1不用存储,只要默认恢复出来的数据加1即可)

4. 这样要编码的x由两部分组成:

a. 第一部分由q个1加上一个0组成,表示q。

b. 第二部分由m个位组成,表示r。

恢复算法:

如果读入1,则继续往后读,直到读入0,此时读入的1的个数就是q。

之后的m位(m事先约定了)为r。

所以可以计算出x = qb + 1 + r = q * 2^m + r + 1。

Reference

[1]. http://fastcompression.blogspot.com/p/lz4.html

[2]. http://jpkc.zust.edu.cn/2007/dmt/course/MMT03_05_1.htm

[3]. http://jpkc.zust.edu.cn/2007/dmt/course/MMT03_05_2.htm

[4]. http://hi.baidu.com/guoliqiang2006/item/127c8f989b494b4ef14215db

[5]. http://blog.chinaunix.net/uid-17240700-id-3347894.html

[6]. http://jpkc.zust.edu.cn/2007/dmt/course/Mmt03_02_2.htm

[7]. http://tukaani.org/xz/

速度之王 — LZ4压缩算法与其他算法的比较相关推荐

  1. 速度之王 — LZ4压缩算法(一)

    LZ4 (Extremely Fast Compression algorithm) 项目:http://code.google.com/p/lz4/ 作者:Yann Collet 本文作者:zhan ...

  2. lz4压缩算法java实现_LZ4压缩算法分析

    LZ4压缩算法是LZ算法系列中的一种,而且网上也号称是目前最快的压缩算法之一,现没时间亲测也不对LZ系列算法展开讨论只分析LZ4.LZ4算法有两种压缩方法,一种侧重于压缩速度,另一种侧重于压缩比,现讨 ...

  3. golang常用库之- pierrec/lz4包 | lz4命令、lz4压缩算法(高压解速度)

    文章目录 golang常用库之-golang常用库之- pierrec/lz4包 | lz4压缩算法(高压解速度) LZ4压缩算法 lz4使用场景 lz4命令工具安装和使用 pierrec/lz4包 ...

  4. lz4压缩算法--速度之王

    简介 lz4是目前综合来看效率最高的压缩算法,更加侧重压缩解压速度,压缩比并不是第一.在当前的安卓和苹果操作系统中,内存压缩技术就使用的是lz4算法,及时压缩手机内存以带来更多的内存空间.本质上是时间 ...

  5. LZ4压缩算法实现思路详解

    最近遇到一个需求,需要使用LZ4的流式压缩来减少流量开销.笔者也是第一次接触LZ4算法,但速度之王的名声早已如雷贯耳.需求本身要求我使用go语言来编写一套LZ4压缩工具库,因为github上的go语言 ...

  6. lz4压缩算法java实现_深入浅出lz4压缩算法

    简介 lz4是目前综合来看效率最高的压缩算法,更加侧重压缩解压速度,压缩比并不是第一.在当前的安卓和苹果操作系统中,内存压缩技术就使用的是lz4算法,及时压缩手机内存以带来更多的内存空间.本质上是时间 ...

  7. lucene底层数据结构——FST,针对field使用列存储,delta encode压缩doc ids数组,LZ4压缩算法...

    参考: http://www.slideshare.net/lucenerevolution/what-is-inaluceneagrandfinal http://www.slideshare.ne ...

  8. 数仓无损压缩算法:gzip算法

    摘要:一种无损的压缩数据格式,是一个在类Unix上的一种文件解压缩软件. 本文分享自华为云社区<GaussDB(DWS) gzip算法简介>,作者:hw0086. [算法原理] gzip是 ...

  9. lz77优化_数据压缩算法:LZ77 算法的分析与实现

    来源:Dreamo https://www.cnblogs.com/idreamo/p/9249367.html LZ77简介 Ziv和Lempel于1977年发表题为"顺序数据压缩的一个通 ...

最新文章

  1. CCNA基础知识汇总
  2. 手动修改Outlook 2007 邮件签名
  3. 给自己的程序添加BugReport
  4. CS通用项目系统搭建——三层架构第一天
  5. linux内置变量大全,Linux进阶之bash编程四(内置变量)
  6. FastReport.net 使用记录
  7. GitHub上12k Star的《Java工程师成神之路》中终于开放阅读了!
  8. 天气预报为什么要用超级计算机,为什么天气预报不够准确?
  9. 【稀饭】react native 实战系列教程之影片数据获取并解析
  10. 电压源和电流的关联参考方向_电流的参考方向_电压的参考方向
  11. 计算机桌面ie图标无法删除,Win10系统中桌面ie图标无法删除如何解决
  12. # 杂谈偶感 × 基于QFD方法的质量屋构建
  13. 华为mate40Android,【猫哥爆料】史上最强Mate40官宣,坐实年度安卓机皇!
  14. “华为杯”第十七届中国研究生 数学建模竞赛-【华为杯】B题:降低汽油精制过程中的辛烷值损失模型(附优秀论文)
  15. 苹果开发者账号添加设备
  16. mybatis-config.xml配置文件中“http://mybatis.org/dtd/mybatis-3-config.dtd”报错
  17. Html5浪漫结婚请柬婚礼网站模板❤_爱她就给她最美的H5婚礼请柬_(婚庆电子邀请函)含背景音乐...
  18. GraphicsView学习-基本图元使用(2)
  19. 整蛊网页制作html,WordPress模板的整蛊菜单(HTML + CSS)
  20. Oracle建表与创建序列

热门文章

  1. Oracle执行计划解释
  2. Atititi tesseract使用总结
  3. DevExpress控件使用经验总结
  4. [Winodows Phone 7控件详解]控件拾遗
  5. javascript 里Array的一些方法
  6. Flask爱家租房--celery(总结)
  7. matlab ones函数_Matlab中相见恨晚的命令(持续更新)
  8. 前端之 jQuery 入门
  9. Python 第三方模块之 NumPy - 科学计算
  10. python中时间模块