日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

写一个高性能的敏感词检测组件

發(fā)布時間:2023/12/4 编程问答 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 写一个高性能的敏感词检测组件 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

最近寫了一個高性能的敏感詞檢測組件【ToolGood.Words】。

一、高性能,它的效率到底有多快?

如果將正則表達(dá)式的算法效率設(shè)為1,高性能可達(dá)到正則表達(dá)式的1.5萬倍。

?

二、選一個巧妙的算法:

AC自動機Aho-Corasick Automation)算法在1975年產(chǎn)生于貝爾實驗室,是著名的多模式匹配算法之一;一個常見的例子就是給定N個單詞,給定包含M個字符的文章,要求確定多少個給定的單詞在文章中出現(xiàn)過;AC自動機在匹配文本時不需要回溯,處理時間復(fù)雜度與pattern無關(guān),僅是target的長度O(N);構(gòu)建AC自動機的時間復(fù)雜度。

AC自動機的構(gòu)建主要由三個步驟:

2.1、針對所有模式串構(gòu)建Trie樹。

2.2、針對所有Trie樹上的接點構(gòu)建Fail指針:Fail指針指向的是如果當(dāng)前節(jié)點匹配失敗,則從通過Fail指針指向的新的節(jié)點開始匹配,但新的節(jié)點必須滿足所在在新節(jié)點模式串的前綴必須是轉(zhuǎn)移前的節(jié)點所在模式串的子串,也就是已經(jīng)匹配成功的部分。

2.3、正式匹配過程:
a)從Trie樹root節(jié)點開始,每次根據(jù)讀入的字符沿著自動機向下移動。
b)當(dāng)讀入的字符,在分支中不存在時,遞歸走Fail指針路徑。如果走Fail指針路徑走到了root節(jié)點,則跳過該字符,處理下一個字符。
c)因為AC自動機是沿著文本移動的,所以在讀取完所有輸入文本后,最后遞歸走失敗路徑,直到到達(dá)根節(jié)點,這樣可以檢測出所有的模式。

?

三、優(yōu)化AC自動機算法

細(xì)看AC自動算法匹配過程,在(b)步驟我們會發(fā)現(xiàn)節(jié)點匹配失敗后會順Fail指針繼續(xù)執(zhí)行,這個步驟可以優(yōu)化,優(yōu)化Fail指針,將相同的節(jié)點合并成一個同一個節(jié)點。

?

四、填平性能低洼地

優(yōu)化AC自動機算法后,測試代碼后會發(fā)現(xiàn)代碼性能沒有太大提升。

經(jīng)測試發(fā)現(xiàn),TrieNode獲取下一節(jié)點的方法(TryGetValue)占用了90%的計算量。

分析Trie樹有兩個特點:1root節(jié)點下有大量子節(jié)點,2、中間節(jié)點的子節(jié)點數(shù)量很少。

優(yōu)化TryGetValue方法:

1、root的子節(jié)點轉(zhuǎn)成數(shù)組類型

2、修改TryGetValue方法內(nèi):

?

public? class? TrieNode { ???? public? bool? End {? get ;? set ; } ???? public? List< string > Results {? get ;? set ; } ???? private? Dictionary< char , TrieNode> m_values; ???? private? uint? minflag =? uint .MaxValue; ???? private? uint? maxflag =? uint .MinValue; ???? //.... ???? public? bool? TryGetValue( char? c,? out? TrieNode node) ???? { ???????? if? (minflag <= ( uint )c && maxflag >= ( uint )c) { ???????????? return? m_values.TryGetValue(c,? out? node); ???????? } ???????? node =? null ; ???????? return? false ; ???? } }

?

五、優(yōu)化后的代碼段

?

public? class? StringSearch { ???????? TrieNode _root =? new? TrieNode(); ???????? TrieNode[] _first =? new? TrieNode[ char .MaxValue + 1]; ???????? //..... ???????? public? bool? ContainsAny( string? text) ???????? { ???????????? TrieNode ptr =? null ; ???????????? for? ( int? i = 0; i < text.Length; i++) { ???????????????? TrieNode tn; ???????????????? if? (ptr ==? null ) { ???????????????????? tn = _first[text[i]]; ???????????????? }? else? { ???????????????????? if? (ptr.TryGetValue(text[i],? out? tn) ==? false ) { ???????????????????????? tn = _first[text[i]]; ???????????????????? } ???????????????? } ???????????????? if? (tn !=? null ) { ???????????????????? if? (tn.End) { ???????????????????????? return? true ; ???????????????????? } ???????????????? } ???????????????? ptr = tn; ???????????? } ???????????? return? false ; ???????? } }

?

?六、性能對比圖,10W次對比

ToolGood.Words內(nèi)的非法詞(敏感詞)檢測類:StringSearch、WordsSearch、IllegalWordsSearch、IllegalWordsQuickSearch;

注:C#自帶正則很慢,StringSearch.ContainsAny是Regex.IsMatch效率的1.5萬倍。

Regex.Matches的運行方式跟IQueryable的類似,只返回MatchCollection,還沒有計算。

TrieFilter,FastFilter來源:?http://www.cnblogs.com/yeerh/archive/2011/10/20/2219035.html

?

七、開源項目

碼云:?https://git.oschina.net/toolgood/ToolGood.Words

GitHub:?https://github.com/toolgood/ToolGood.Words

原文地址:http://www.cnblogs.com/toolgood/p/6284718.html


.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注

總結(jié)

以上是生活随笔為你收集整理的写一个高性能的敏感词检测组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。