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,然而有很多人開...