原方法與正則表達式方法對比性能分析
0.前言
寫這篇隨筆的原因呢,還得感謝此次結對編程與南通大學鞠老師的合作,因時間較短開發出來的小程序在性能上並沒有足夠多的考慮。其實我一直以來都有一種習慣,就是對於一些細枝末節的程序,並不太願意花時間去考慮效率。更多地時間願意花在算法的調優上,而本次的討論,也確實影響了我,也是促動我這次認真分析一些小地方的效率情況。
github地址 : https://github.com/yuan574954352/WordCountByRegular
1.設計實驗
在之前的實現之中的主要邏輯如下,
其中討論的重點是繼Readline()、Split()之後,對於單詞的匹配處理。因此我對於其他程序依舊不改變,只改變dealline()中的代碼,采用典型的控制變量思想。
1.1 控制變量
【原方法】
String subString = line.substring(first, end + 1);
int lengthSub = subString.length()>4? 4:subString.length();
for (int j=0 ;j<lengthSub;j++)
{
if(isNumber(subString.charAt(j))){
isSubHavaNum = true;
}
}
其中SubString是截取的單詞,原方法對於單詞的判斷是基於單詞前四個字母中是否含有數字。
【正則表達式方法】
String subString = line.substring(first, end + 1);
boolean idWord = subString.matches(Reg);
if(idWord) {
其中Reg為正則表達式。利用matches方法判斷是否繼續操作。
2.實驗測試
測試文件為一篇英文文獻:Tack: Learning Towards Contextual and Ephemeral Indoor Localization With Crowdsourcing
為了盡量避免因偶然誤差帶來的影響,我對每個方法均使用JProfiler分析3次,得出平均值。
2.1從運算正確結果分析:經測試兩種方法得出結果一樣,且均為下圖:
感興趣讀者可自行測試,在此不再贅述。
2.2從性能分析
原方法 |
||
|
dealline運行總時間 |
程序運行總時間 |
第一次 |
40,371 |
64,310 |
第二次 |
28,669 |
43,391 |
第三次 |
35,067 |
45,114 |
正則表達式方法 |
||
|
dealline運行總時間 |
程序運行總時間 |
第一次 |
54,980 |
68,832 |
第二次 |
49,169 |
63,095 |
第三次 |
35,058 |
60,150 |
結論一:
我們定義 T(dealline)/T(Main) = 行處理率.
則在原方法中:行處理率1 = 62.77 %,行處理率2 = 66.07%,行處理率3 = 77.72%
均行處理率 = 67%
在正則方法中: 行處理率1 = 79.87 %,行處理率2 =77.93%,行處理率3 = 58.28%
均行處理率 = 72%
從以上分析,我們很明顯的看到,正則表達式的方案並不會比我們原來使用的方案提高效率!反而使用正則表達式程序會花費大量時間在 java.lang.String.matches 方法上。
結論二:
事實上,正則表達式方案反而會使方案降低效率,其中平均降低效率為 0.015s/1.4萬字母。而這樣的效率降低在現實中是完全可以接受的。
換句話說就是 你有一個 100萬字母的英文文本,詞頻統計效率才會下降1s,而且考慮到本人計算機本身計算效率不高,這樣的效率改進是沒多大意義的!
原方法與正則表達式方法對比性能分析