多模匹配-AC與WM算法實測


1     概述

         在某海量數據分析系統中,使用AC多模改進算法做多模匹配,作為數據分類和分發的第一道關口。部署時間較長后,內存占用較大,預處理時間隨模式串數量的增加呈指數級增長,到達10W條模式串的時候已經無法正常運行。為滿足需求,研究算法性能,在AC改進算法無法打成需求的情況下,研究WM匹配算法並進行改進,測試可支持10萬級別的規則加載。並測試內存占用、預處理時間、匹配時間、文本檢索效率等其他性能參數。

2     AC改進算法

2.1    基本思路

AC算法是基於有限自動的多模算法,在預處理階段把模式集P裝換為一個模式匹配機,稱為AC自動機。AC自動機由一系列狀態組成,每個狀態用一個數字表示。具體的算法如下描述。

2.2    預處理流程

1)   計算出所有模式串的最短長度記為m

2)   構造模式樹

for  每一個模式串

處理節點 = 根節點

From 尾字符 to 頭字符

              If (處理節點的一個子節點 ==  當前處理字符)

                        處理下一個節點

              else

                        創建新的節點存放處理字符 添加到 處理節點的子節點中

將當前模式串 添加到 處理節點指向的鏈表(模式串相同的鏈表)

3)   跳轉表Shift1

Shift1表的大小是256,等於模式串字母表的大小。用於存放模式樹中根節點的子節點匹配失敗時的跳轉步數。

for ( j = 0; j< 256; j++)

Shift1[j] = m

for  每一個模式串

for ( j = 0; j < 模式串長度; j++)

           if (Shift1 [字符]  > 模式串長度 – j – 1 )

                    Shift1 [字符]  =  模式串長度 – j – 1

4)   跳轉表Shift2

Shift2 存放的是非根節點的子節點匹配失敗時的跳轉步數。每個節點都有一個Shift2表。

處理節點A = 根節點

對模式樹廣度遍歷

           For  處理節點A的  空子節點(X)

                    處理節點A的Shift2[X] = m + 樹的深度

           設 當前失敗節點F = 處理節點A的父親節點的失敗節點

While當前失敗節點F 不是 根節點

if 當前失敗節點F 存在 處理節點A的字符

     處理節點的失敗節點 =  當前失敗節點

         當前失敗節點的Shift2[X] = Min(當前失敗節點的Shift2[X] , 處理節點A的深度)

         Break;

當前失敗節點 = 當前失敗節點的父親節點的失敗節點

           If當前失敗節點 是根節點

處理節點的失敗節點 =  根節點

           For 每個模式串結尾狀態節點 t

                    If  t的失敗節點 state 不為根節點

                    對以state為根節點的樹中的節點 r

r 節點的Shift2[X] = Min( t節點的深度+ state節點的深度- r節點深度,Shift2[X])         

2.3    匹配流程

處理節點 = 根節點

處理字符 = 主串T的第m個字符

while 處理字符 <= T 的最后一個字符

         If 處理節點的子節點 = 處理字符

                   While處理節點 != 根節點

                            If處理節點指向的鏈表非空

               鏈表指向的模式串 全部 匹配中

      處理節點 = 處理節點的失敗節點

處理節點 = 處理節點的子節點

處理字符 = 處理字符的前一個字符

Else

if  處理節點 是 根節點

      處理字符 = 處理字符 +  Shift1[處理字符]

      處理節點 = 根節點

Else

      處理字符 = 處理字符 +  Shift2[處理字符]

      處理節點 = 根節點

2.4    舉例說明

輸入模式串 :{ they , she , his , hers }

1)   預處理階段

  • 創建模式樹

  • Shift1表 

Shift1位置

t

3

h

1

e

0

y

0

s

0

i

1

r

1

others

3

                  

 

 

 

 

 

 

 

 

 

 

 

 

  • Shift2表

                 

                   圖1:失敗指針

      

                   圖2:Shift2初始化

      

圖2:進一步處理Shift2表

 

3     WM改進算法

3.1    基本思路

         WM主要是利用SHIFT、HASH、PREFIX三張表。SHIFT[]就是一跳轉表,一張記錄向右滑動距離的表。HASH和PRIFIX表是對模式串的后綴及前綴分別做的索引。匹配時當SHIFT[i]=0時,說明模式串patterns肯定有暫時匹配上的,這時HASH[]表用來指明誰暫時匹配上了,然后對暫時匹配中的每一個模式串匹配進一步匹配。主要是先用PREFIX表匹配前綴,如果前綴也匹配上了,再匹配整個模式串。具體如下:

3.2    預處理流程

1)       計算出所有模式串的最短長度記為m,選擇WM算法的處理塊大小為B = 2。(B一般為2或3)

2)       構造Hash表

Hash[i]存放一個指向鏈表的指針,鏈表存着這樣的patterns(第m-2、m-1、m 三位通過hash function計算是i)。Hash []表大小為256*256*256。

3)       構造Shift表

Shift表的大小是256*256。

Shift表中初始值賦值為m-B+1

for  每一個模式串

for  (j = m-1; j > = B-1 ; j--)

對模式串中第 j-1、j 兩個字符計算hash值,記為n

Shift[n] = min (Shift[n] , m-1-j)

4)       構造Prefix表

Prefix[i]存放第i個模式串的首B個字符的哈希值。匹配時用於匹配中了后綴之后再匹配前綴,可以減少匹配整個模式串的可能。

3.3    匹配流程

從待匹配主串T 的第m-B個字符開始處理,當前處理字符位置為 i,總長度為LN。

i = m-B

while  i <=  LN-B

對第i 、i+1 兩個字符計算hash值,記為n

從Shift表中取出 Shift[n]的值,表示跳轉的步數,記為 shift

           While shift > 0

                    i += shift

                    if  i > LN-B

                             return  匹配中的模式

                    n = 第i 、i+1 兩個字符計算hash值

shift = Shift[n]

           n = 第i-1、 i 、i+1 三個字符計算hash值

           此處表示匹配中當前處理字符,從Hash表中Hash[n]獲取對應的模式串

           While 模式串存在

判斷模式串的頭兩個字符和主串中對應的字符是否相等

                             如果相等

                                       判斷整個模式串和主串的相應位置

                                                相等,表示匹配中,存入匹配中的數組

                    取模式串的下一個模式串next

           n = 第i+1、i+2兩個字符計算hash值

           shift = Shift[n] + 1

           i += shif

 

 

4     兩種算法的比較

算法

內存占用

預處理時間

匹配效率

模式串限制

AC改進算法

比較大

O(N*L*L)

模式串內容無影響

WM改進算法

O(N*m)

較高

模式串內容有影響

最短長度不能小於2,且長度最好是相差不大

注:表中的L是模式串的平均長度,m是模式串的最短長度,N是模式串的個數。

4.1    測試對比

  • 測試串來源

隨機產生的字符串。字母從

abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.,;*&^$#@!隨即選取。

  • 測試機器

CPU:E56系列(四核) *2

內存:16G

系統硬盤:500G SATA

存儲:450G SAS*6

4.2    加載測試

測試兩種算法占用內存和加載時間

1、字符串長度10-20,測試字符串條數10000條

初始化空間

AC算法加載條數

WM算法加載條數

AC內存

WM內存

AC加載耗時

WM加載耗時

10240

4847

10000

222m

71m

40.01s

0.17s

9000

2394

9000

124m

71m

11.54s

0.13s

5000

2394

5000

111m

68m

11.14s

0.14s

2000

2000

2000

97m

67m

8.10s

0.14s

         2、字符串長度20-40,測試字符串條數10000條

初始化空間

AC加載條數

WM加載條數

AC內存

WM內存

AC加載耗時

WM加載耗時

10240

2261

10000

214m

71m

20.13s

0.17s

9000

1133

9000

118m

71m

6.28s

0.14s

5000

1133

5000

111m

68m

6.34s

0.14s

2000

1133

2000

102m

67m

6.28s

0.13s

4.3    匹配測試

測試兩種算法的匹配速度

1. 初始化為10240,加載字符串長度6-30,匹配次數100000次

待匹配串長度

加載規則條數

AC加載時間

WM加載時間

AC總匹配耗時

WM總匹配耗時

100

100

1.3s

0.1s

1.0s

0.58s

100

200

1.3s

0.11s

1.1s

0.52s

100

400

1.6s

0.13s

1.2s

0.53s

100

800

3.0s

0.13s

1.3s

0.65s

100

1600

8.1s

0.13s

1.5s

0.78s

100

3200

27s

0.13s

1.6s

0.91s

100

6400

 

0.17s

 

1.2s

4.4    實際數據測試

4.4.1         某地A系統數據

規則條數是2447,虛擬機內存1G

a)         預處理性能測試

算法

開辟空間

成功加載條數

內存占用

加載時間

AC改進算法

10240

2092

162m

5.4s

WM改進算法

3000

2447

67m

0.1s

 

b)         匹配性能測試,匹配次數是100000。

匹配字符

匹配字符長度

AC改進算法總耗時

WM改進算法總耗時

某類賬號A

20

0.1s

2.5s

某類賬號B

10

0.1s

0.07s

URL

21

0.1s

0.52s

某類賬號C

15

0.1s

0.18s

26字母

26

0.03s

0.03s

 

4.4.2         某地B系統數據

規則條數是3171,虛擬機內存1G

a)          預處理性能測試

算法

開辟空間

成功加載條數

內存占用

加載時間

AC改進算法

10240

3171

185m

14.4s

WM改進算法

4000

3171

67m

0.1s

 

b)       匹配性能測試,匹配次數100000次。

匹配協議

匹配字符長度

AC改進算法總耗時

WM改進算法總耗時

某類賬號A

32

0.2s

1.1s

某類賬號B

24

0.2s

0.1s

TEL

17

0.15s

1.2s

某類賬號C

55

0.5s

0.8s

26字母

26

0.02s

0.02s

 

4.5    測試總結

根據以上測試結果發現,以下方面影響到整個匹配程序的性能:

內存占用:WM改進算法比AC改進算法的內存小很多。

預處理:  WM改進算法比AC改進算法的預處理時間小很多。

匹配速度:WM算法的匹配速度跟加載的模式串內容有很大的關系。

AC算法跟加載的模式串內容無關。

前綴:如果前綴內容大量相似,WM改進算法的Shift表和HASH表沖突比較多,匹配慢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM