2011-11-25 66 views
5


我在一些我想優化的代碼中發現了這個。 這裏是snipet:這是一個正常的Java正則表達式行爲嗎?

tempString = bigBuffer.replaceAll("\\n", ""); 
tempString = tempString.replaceAll("\\t", ""); 

然後,我決定明智地使用正則表達式和我這樣做:

tempString = bigBuffer.replaceAll("[\\n\\t]", ""); 

後來朋友告訴我,做這個:

tempString = bigBuffer.replaceAll("\\n|\\t", ""); 

由於我想知道我的更改的結果,我做了一個測試來驗證它是否是一個很好的優化。所以,(java版本「1.6.0_27」)的結果是第一個代碼是引用100%。

隨着管道它是121%,所以它需要更多的時間來執行任務。

用方括號表示它是52%,因此執行該任務所用的時間較少。

爲什麼正則表達式應該是相同的?

馬丁

+0

爲什麼它應該是相同的? – BoltClock

+0

我認爲它應該是相同的,因爲它做同樣的事情。當管道使用單個字符時,編譯器可能需要優化。 – Martin

回答

4

第一代碼片段看起來通過bigBuffer兩次,第一次更換的新生產線,並第二次更換的標籤。

第二個代碼片段僅搜索bigBuffer一次,檢查每個字符是否是其中一個。這隻會在一半的時間內完成速度。

第三位的代碼片段可能編譯得不好,導致第一個代碼算法的版本特別差,儘管我沒有仔細檢查通過正則表達式編譯的路徑。

雖然在測試上出色的工作。相對時間(基於百分比)是有用的,絕對時間(毫秒或某些這樣的)不是。

2

一般來說,角色類([abc])往往比等效替換更有效率(a|b|c),所以我不知道你的朋友爲什麼會這麼建議。但是在Java中,只匹配拉丁語1的所有字符(即前256個Unicode代碼點)的字符類進一步優化。這可能就是爲什麼你會看到第二和第三種技術之間的巨大差異。

同樣,這只是Java。在Perl中,我希望交替和字符類之間的差異可以忽略不計,它是一個更成熟的實現。而在grep中,無論您使用三種方法中的哪一種,都可能難以衡量差異 - 這就是那麼快。

但是,作爲一個經驗法則,如果您在使用字符類或交替之間進行選擇,則應該更喜歡字符類。這可能不會更快,但它絕對不會變慢。如果使用不當,交替會對性能造成災難性影響。

+0

感謝您的經驗法則,我會確保我的朋友知道它。 – Martin