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
上面的字串壓縮後的位元組序列是(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原始碼,照著上面的例子驗證一下,本人已經測試過了。