1. 程式人生 > >壓縮演算法gorilla paper encoding原理

壓縮演算法gorilla paper encoding原理

目錄

引:

IEEE754

浮點數簡述

舉例

演算法原理

工作流程

壓縮結構

簡要分析

壓縮率測試

小結:


引:

從之前研究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位

結果:010000001010‬0001111110000000000000000000000000000000000000000000

轉換成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的部分開始看,就通俗易懂了。

有時間的話,自己實現這個壓縮演算法,做一些資料測試,看看壓縮率根據資料的特點最高最低能怎樣。