UBB解析優化的心得 Regex建構函式的效能

2021-04-13 14:23:42 字數 2220 閱讀 6648

2023年08月02日 14:37:00

昨天和今天,我都在對我之前寫的ubb解析**進行效能優化。優化的結果是:1個具有600多個ubb標籤的文字,包含多層ubb巢狀,優化前,解析出這個文字需要2分鐘,優化後解析出這個文字需要1秒鐘。而這次優化,核心優化的技術只有一點:正規表示式regex 的構造位置發生變化。下面我就來慢慢來說這次優化。

ubb解析元件的簡單介紹

需求:1、把支援的14個ubb標籤解析成不同的html文字。這14個標籤包含:**高亮標籤、禁用ubb標籤以及一些通用的ubb標籤。

2、一部分ubb 標籤支援巢狀的解析,比如對以下文字的解析: [b]1[i]2[/i]3[/b] ,要求2這個文字,需要解析成加粗同時是斜體;

3、一部分ubb標籤不支援巢狀的解析,比如:**高亮的ubb標籤括的範圍內,任何ubb標籤都不起作用。

我的設計:

先把一段包含ubb標籤的文字解析成乙個樹,樹的每乙個末梢節點都是不能再繼續拆分下去的一段文字,即:其下沒有起作用的巢狀ubb標籤。然後把這個樹的每個節點解析內容合併成一段新的文字。

這個演算法的瓶頸在把文字解析成樹,解析成樹後的計算,系統消耗很少,可以忽略不計。

解析成樹的演算法,我的設計如下:

先在這個文字中,使用正規表示式從頭開始找起,找到第乙個系統支援的ubb標籤,比如我們找到了乙個[b] 文字。然後從找到位置開始,向後,找 [/b] 文字,這兩個尋找都是使用的正則來尋找,根據這兩個尋找的三種結果,分別進行處理.

然後再用遞迴演算法,不停的迴圈上述處理邏輯,從而把文字解析成樹。

我的**優化

優化前效能不高的**:

// 在一段文字中,從指定位置開始,找到系統支援的ubb標籤文字,比如之前的例子,找 [b] [i] 這些文字

private bool matchbegintag(int beginpos, out ubbcodefragmenttype ubbtype, out string ubbparametervalue, out int tagprepos, out int tagendpos)

// 從指定位置開始,向後 找指定標籤的結束標籤

private bool matchendtag(int beginpos, string tagname, out int tagprepos, out int tagendpos)

上述兩個函式分別實現之前說的兩個功能,這兩個函式會被頻繁的遞迴呼叫,比如我之前說的場景,600多個ubb標籤的文字,這兩個函式會被600次的呼叫到。

我的優化方法

我通過使用 jetbrains dottrace 3.0 工具,看到 regex 的建構函式被頻繁的呼叫,累計呼叫花費的時間非常巨大,我在這裡對它進行**調整.

對於 matchbegintag 函式, 由於它用的 regex rx_matchbegintag 是固定的,很簡單,我把這個物件放在函式體之外,把它定義成靜態成員,這樣它只需要構造一次,改造成如下**方式:

private static regex rx_matchbegintag = new regex(@"/[(?

[a-za-z]+)(=(?

[^/f/n/r/t/v/]]*))?/]", regexoptions.compiled | regexoptions.ignorecase);

這乙個的改造工作,讓我在600多個ubb文字的解析時間從2分鐘下降到12秒鐘.

對於 matchendtag 函式體內的 regex ,這個是動態構造的,顯然不能用前面的這個方法。使用乙個靜態regex 物件來記錄。

我的做法是,建立乙個 dictionary

ht_endtagregexarray,這個結構中,儲存了系統支援的14個ubb標籤對應的正規表示式構建的靜態regex 物件。在這個類被第一使用的時候,上述14個regex 物件被構造,之後不用再構造,直接使用。

這樣的改造工作後,讓我在600多個ubb文字解析的時間,從上乙個優化結果12秒變成了1秒鐘。

當然我還作了其他優化的工作,但是這些其他的優化工作的結果並不明顯。可以一筆帶過。

分析:我們優化前**是在遞迴中使用 new regex 。

這樣,我們建立的每乙個 regex 物件都沒有過生命週期,更不可能被gc釋放了,同時並存600個regex 。就是不考慮構造的花費,這個並存的花費都是非常驚人的。更不用說構造的花費了。

結論:一定要避免頻繁的 new regex 物件,這個過程很耗資源。

Ogre的渲染優化心得

做商業網路遊戲的話,效率是乙個不可避免的話題,為了留更多的空間給客戶端的邏輯,那麼渲染模組就應該盡量高效.小弟只 一下ogre的渲染優化,以大家熟悉的天龍八部為例.以網上流傳版本的天龍 來看,ogre和cegui部分的渲染都有嚴重的效能問題,ogre 地形的實現,乙個tile,只按材質做了批次優化,...

android的記憶體優化心得

1.1 利用執行緒池的概念,來操作執行緒,減少執行緒的建立和銷毀的時間 1.2 在用過多的message的時候,用message的obtain方法,利用訊息池建立訊息 1.3 採用static的handler來處理執行緒,避免handler的引用導致防止gc時因為handler有引用導致,activ...

SEO優化的進修SEO優化辦法心得

seo優化的進修seo優化辦法心得 seo實在就是一度很單調的活,必需臨時保持才會順利。保持本人的貨色。蛛蛛就會很喜愛,一直的模擬外人換來的就是你會被k。seo是一項臨時和富饒應戰性的任務,必須要保持去復舊,搜尋引擎和人一樣都喜愛新的 活的有 的貨色。現正在越來越多的人開端進修seo,然而有很多人開...