壓縮演算法gorilla paper encoding原理
目錄
引:
從之前研究TSM檔案格式,發現float型別的value是以facebook的gorilla paper encoding的演算法進行壓縮。
當時沒有去深究,現在把這個演算法的詳細邏輯給理出來.
這個演算法是float的壓縮,首先得清楚float的在記憶體中是如何儲存的。
IEEE754
浮點數簡述
以64位float為例,下文float都是指64位float
IEEE754規定了float在記憶體中的儲存方法,以 num * 2^n 來描述(num為二進位制的1.xxxxx )
符號位顧名思義,正數為0,負數為1
指數位是 n + (2^10 - 1)也就是 n+1023
尾數位就是 num 小數點後面的所有值了。
舉例
以數字 2300為例。
其二進位制為:100011111100
轉化成指數形式:1.00011111100*2^11
指數位就是 11+1023 = 1034, 二進位制:10000001010, (指數位基準為1023)
尾數位: 取小數點後面的值 00011111100
剩下的尾數位補0,湊成一共64位
結果:0100000010100001111110000000000000000000000000000000000000000000
轉換成16進位制:40A1F80000000000
由此可知,float在記憶體中的儲存形式。可以看出來,有效數字普遍靠前。
演算法原理
工作流程
gorilla paper encoding就是針對這些8位元組的float進行壓縮的。
這個壓縮過程其實就是一個位元組流(位流)按照一定格式的不斷追加。
詳細流程如下
第一個位元組置為 0x10, 代表這個演算法名字
接著寫入第一個數,無壓縮,8位元組。
寫入一個數流程圖(從第二個數開始)
在所有數都新增完之後,再新增一個結束的數字
0x7FF8000000000001, not-a-number,代表結束符
最後補全一些位0,使得位元組流完整。
壓縮結構
從流程圖可知,新增一個數 就有三種情況:
從第一個數開始是一個完整的8 bytes數,後面的所有樹存的都是與上一個數異或得到的delta值。
簡要分析
存delta值有什麼好處?
1. 通過delta值也很容易求出實際值
delta = A^B
那麼 B = delta^B
2. 相近的數字(這個相近其實很寬),異或的delta值 前導0 和 後導0 數量會很多,也就是有效位會很少,提高壓縮率
舉例:
2300 , float型別表示為 40A1F80000000000
10000, float型別表示為 40C3880000000000
這兩個數字異或delta = 0062700000000000
二進位制0000000001100010011100000000000000000000000000000000000000000000
前導0, 9個; 後導0, 44個。 有效位數,11。
壓縮率測試
寫入800個整數,以浮點數形式壓縮,實測結果如下:
原始資料型別 | 數量 | 資料規律 | 原始資料size | 壓縮後資料size | 壓縮率 |
INT | 800 | 隨機數0~100000 | 3200 bytes | 2156 bytes | 67% |
INT | 800 | 隨機數1000~10000 | 3200 bytes | 1816 bytes | 57% |
INT | 800 | 起始為10000 每次遞增0~500隨機數 |
3200 bytes | 1793 bytes | 56% |
小結:
這篇描述了gorilla paper encoding的演算法邏輯,回頭看來很簡單,一開始從decode程式碼開始看就很難懂,後來從encode的部分開始看,就通俗易懂了。
有時間的話,自己實現這個壓縮演算法,做一些資料測試,看看壓縮率根據資料的特點最高最低能怎樣。