最近做給一塊藍芽晶片做了一個decode的功能,資料是用RLE(http://en.wikipedia.org/wiki/Run-length_encoding)流程演算法壓縮的。為什麼選用RLE演算法,因為藍芽晶片自身memory的局限性,最大隻能獲得不到2K的記憶體,還是不連續,而解壓出的資料有2K多,所以需要一種能夠邊解壓邊發送的演算法,查看現在流行的幾種演算法:霍夫曼演算法,RLE演算法,查表演算法。
| |
壓縮率 |
實現複雜度 |
記憶體佔用量 |
| 霍夫曼演算法 |
小 |
中 |
中 |
| RLE演算法 |
中 |
小 |
小 |
| 查表演算法 |
大 |
大 |
大(一般幾十K) |
由於查表演算法的記憶體佔用量一般需要幾十K,所以所以首先排除,而且比較霍夫曼演算法和RLE演算法,RLE演算法在壓縮率,實現複雜度,記憶體佔用量三個方面都佔有優勢,所以最終選擇RLE作為壓縮和解碼的方法。
花了幾天時間實現了改演算法,今天對其進行了效能測試,發現解壓目標資料需要200多ms,遂決定對其進行最佳化。
step1,還原行解壓函數,減少一百多次的函數調用,但是實驗的結果是反而增加了100多ms,猜測可能是有遠指標調用,遂放棄。
step2,將行解壓函數中,對堆記憶體的訪問換成對棧上資料的訪問,實驗下來時間減小到了70-80ms,效能提升了一倍多。
step3,由於採用的RLE演算法是經過改進過的,n + 1行的資料是和n行資料異或過,所以增加相同資料的幾率,比如有三行資料時1010 1010,理論上是不能壓縮的,當時經過異或,後面兩行資料都變成了0000 0000,便可以採用RLE演算法進行壓縮。所以根據這一特性,在step3做的最佳化是,比較解壓出的值,如果是0,則不需要和上一行的資料進行異或(因為任何數和零異或都不變)。改進後可以將時間減小到30-40ms,又提升了一倍多。
step4,在step3的基礎,在行解壓演算法中,如果檢測到行的剩餘部分都是0,則直接跳過該行剩下的部分。改進後時間減小到了十幾個ms。
所以進過step2-4,效能提升了10倍多。