把並行化的思想用在編譯碼驗證演算法上的實踐

2021-10-09 21:33:44 字數 2915 閱讀 5055

編碼驗證演算法是一種驗證資料序列編碼格式的演算法,比較典型的有utf-8編碼驗證演算法。utf-8驗證演算法用於檢查資料序列是否符合utf-8編碼規範,比如說對常用utf-8編碼的郵件、網頁及應用資料做編碼驗證時,就可以使用utf-8驗證演算法。 本文以go語言開源社群的utf-8驗證演算法優化案例為例,講解通用的演算法分析、優化方法。

1. go語言的utf-8編碼驗證演算法

go語言實現了utf-8編碼驗證演算法用於檢查utf-8編碼資料,主要基於utf-8的可變長編碼特點設計了驗證演算法,utf-8編碼使用1到4個位元組為每個字元編碼,ascii編碼屬於utf-8編碼長度為1個位元組的情況。 utf-8驗證演算法針對這個特點,先取乙個字元判斷是否屬於ascii編碼,再檢查是否屬於其他型別的utf-8編碼。**如下:

// 優化前的utf-8驗證演算法,先取乙個位元組檢查是否為ascii,再驗證字元是否屬於其他型別的utf-8編碼

func valid(p byte) bool

// 驗證byte字元是否屬於其他型別的utf8編碼

x := first[pi]

if x == xx

size := int(x & 7)

if i+size > n

accept := acceptranges[x>>4]

if c := p[i+1]; c < accept.lo || accept.hi < c else if size == 2 else if c := p[i+2]; c < locb || hicb < c else if size == 3 else if c := p[i+3]; c < locb || hicb < c

i += size

}return true

}

通過分析go語言優化前的utf-8驗證演算法,發現它也用於ascii字元的檢查。在長篇的英文電子郵件中,連續出現大量的ascii編碼也是常見的,下圖這篇英文郵件包含1705個ascii字元。

使用上述的utf-8驗證演算法對英文郵件內容進行編碼檢查時,需要進行1705次比較操作,如下圖:

由此可見,在需要驗證大量ascii編碼資料的場景下,優化前的utf-8編碼驗證演算法採用單個字元比較的方式檢查編碼,直到迴圈檢查完整個資料,演算法的執行耗時大,效能有待提公升。

針對utf-8編碼驗證演算法中處理ascii編碼字元檢查次數多、執行耗時大的問題,可以利用並行化程式設計思想,一次同時處理多個ascii編碼字元的檢查,減少比較的次數,加快驗證速度,提公升演算法效能。 go語言的utf-8驗證演算法應用了基於並行化程式設計思想的演算法優化方案,一次同時檢查8個ascii編碼,大大提公升了演算法的執行效能。 演算法優化前後的**對比如下:

優化後的**分析如下:

// 優化後的**,基於並行化程式設計思想,一次檢查8個byte是否為ascii字元

func valid(p byte) bool

p = p[8:]

}// 每次驗證乙個byte是否為utf-8編碼

......

}

為了進一步分析並行化的優化技術,使用反彙編的方法得到了演算法優化前後的彙編**。優化前的彙編**如下:

優化後的彙編**如下:

分析發現,優化前的**,使用1個unit8變數儲存資料進行編碼驗證,對應到彙編**使用movbu指令取乙個b(1個byte)的資料到暫存器r4,一次驗證1個byte資料的編碼。 優化後的**,使用2個unit32變數儲存資料進行編碼驗證,對應到彙編**使用movwu指令分別取乙個w(4個byte)的資料到暫存器r3和r4,一次驗證8個byte資料的編碼。 該優化方法通過在go語言**中使用儲存資料更多的unit32變數型別,增加了彙編指令中暫存器儲存的資料量,在暫存器做比較操作時,實現了更多編碼資料的並行化驗證

使用go benchmark測試優化前後的演算法效能,再用go benchstat對比優化前後的效能測試結果,整理到如下**:

測試項測試用例

優化前每操作耗時 time/op

優化後每操作耗時 time/op

耗時對比

benchmarkvalidtenasciichars-8

長度為10的byte切片

15.8 ns/op

8.00 ns/op

-49.37%

benchmarkvalidstringtenasciichars-8

長度為10的字串

12.8 ns/op

8.04 ns/op

-37.19%

[注]-8表示函式執行時的gomaxprocs值,ns/op表示函式每次執行的平均納秒耗時。

效能測試結果顯示,utf-8編碼驗證演算法優化後,驗證ascii編碼的平均耗時減小,效能提公升明顯最高達49%。

go語言的utf-8驗證演算法優化案例,從乙個具體的場景出發分析演算法存在的效能問題,給出了基於並行化程式設計思想的優化方案,並最終驗證了優化結果,是乙個值得學習借鑑的演算法優化實踐。 案例中的並行化程式設計思想不僅可以用於優化資料的編碼驗證,更是能用於優化資料的編碼、解碼、壓縮和儲存等多種場景。

以最簡單的思想用javascript實現楊輝三角

基本思想 利用楊輝三角的基本性質之一,每個數字等於上一行的左右兩個數字之和。即第n 1行的第i個數等於第n行的第i 1個數和 第i個數之和,這也是組合數的性質之一。即 c n 1,i c n,i c n,i 1 為了使得函式能在後期的使用中更方便,使復用性更高,在pascal函式中實現將楊輝三角的資...

並行的思想設計模組

最近遇到一兩個問題,包括以前遇到的未得到完美解答的問題,有的從前輩的 中領悟,有的從前輩的直接指導中得到解答。例如,去年跟著一位前輩做乙個工程,而工程中,前輩已對每個模組劃分概念,例如,只作為元素的容器,或者作為元素的行為的。但是在實現過程中,發現從程式流程出發,而非從概念出發,只要往容器類內加乙個...

把 optware 用在你的嵌入裝置上

關鍵字 optware,openwrt,dd wrt,linksys wrt54g,wdtv,嵌入系統,開發板 接觸 wireless 的朋友可能用過 linksys 的 wrt54g,而且可能還使用過經過改造的 dd wrt firmware,正是當初 wrt54g 的 open source 導...