1. 程式人生 > >LZ4壓縮演算法分析

LZ4壓縮演算法分析

LZ4壓縮演算法是LZ算法系列中的一種,而且網上也號稱是目前最快的壓縮演算法之一,現沒時間親測也不對LZ系列演算法展開討論只分析LZ4。LZ4演算法有兩種壓縮方法,一種側重於壓縮速度,另一種側重於壓縮比,現討論的是側重於壓縮速度的方法。

現給定字串dfabcdefghijklmnabcdkkkkkk,後面出現的“abcd”可以用前面的“abcd”通過偏移量offset與匹配長度matchLength進行代替,實際上這就是LZ4演算法的主要思想。LZ4演算法的最小匹配長度是4,最後5個字元按照字面量儲存,也就是說當位元組數<=9時是不壓縮的(最後會給出解釋)。

詳細的LZ4編碼資料涉及到的變數如下:

1、字面量值literalValue,即dfabcdefghijklmn

2、字面量值長度literalLength=16

3、匹配長度matchLength=4

4、偏移量offset=16-2=14

編碼格式如下:

token_literalLength(可選)_literalValue_offset_matchLength(可選)

token佔用1個位元組,前4位代表字面量值長度,如果長度值>=15與255(1個位元組的無符號數)進行比較,如果比255大則減去255並寫入1個位元組,將剩餘的值如此迴圈比較,反之直接寫入1個位元組。如字面量長度值為512,token前4位等於15,  literalLength等於512-15=255+242佔用兩個位元組。後四位表示匹配的長度,原理和前面一樣,在實現的時候可以優化一下,因為預設最小匹配長度為4,所以可以將值減4

。如匹配長度為512,token後4位等於15,matchLength等於512-4-15=255+238佔用兩個位元組。literalLength與matchLength為什麼要加入可選,就是這個原因,因為值小於15的時候,4個位元位已經足夠表示了。offset佔用2個位元組,即最大值為65535。

上面的字串壓縮後的位元組序列是(0b11110000)_(1)_(dfabcdefghijklmn)_(14)------(0b01100000)_(kkkkkk)

問題一:為什麼最小匹配值為4?

我個人的理解是因為token佔1個位元組、offset佔2個位元組,只有匹配值大於3的時候才有可能起到壓縮效果。注:為什麼是“有可能”呢,因為壓縮演算法是基於概率

的,比如上面的例子並沒有起到壓縮效果,反而多佔一個位元組。

問題二:為什麼最後的5個位元組按照字面量直接儲存?

我個人的理解是假設給定9個位元組的字串abcdabcde,按照正常流程壓縮時格式如下:(0b01000000)_(abcd)_(4)------(0b00010000)_(e),同樣佔了9個位元組,沒有起到壓縮效果。注意(4)是佔2個位元組的。

有興趣的可以對著lucene的LZ4原始碼,照著上面的例子驗證一下,本人已經測試過了。