javaRegex效率 對於Regex的使用效率問題,我在網上看到的有兩種截然不同的結果,到底它的效率如何,今天我用java來做了個則試。 解決的問題很簡單,從一個字串中把用Regex如href="[^\"]*"的字串儲存到一個list中去。先構造一個長字串,再進行匹配操作。測試代碼如下:
import java.util.LinkedList;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Reg {
public String content = "";
public List userRegList = new LinkedList();
public List userCommonList = new LinkedList();
public List userOneToOneList = new LinkedList();
//傳入的參數為構造的字串長度
public void initContent(int count) {
//選用StringBuffer,可以選用String一試,體現雙方拼接字串的效率差異
StringBuffer sb = new StringBuffer();
for (int i = 0; i < count / 20; i++) {
//為了簡化,統一用一小段來迴圈
sb.append("abc href=\"abcd\"abce");
}
this.content = sb.toString();
}
//使用Regex方式
public void useRegCode() {
Pattern p = Pattern.compile("href=\"[^\"]*\"", Pattern.CANON_EQ);
Matcher match = p.matcher(this.content);
while (match.find()) {
userRegList.add(match.group(0));
}
}
// 主要使用字串中提供的find函數來實現
public void useCommonCode() {
int i = 0;
int index = 0;
while ((index = content.indexOf("href=\"", i)) != -1) {
int endIndex = content.indexOf("\"", index + 6);
i = endIndex + 1;
userCommonList.add(content.substring(index, endIndex + 1));
}
}
// 一個一個字元地去遍曆判斷
public void useOneToOneCode() {
int length = content.length();
for (int i = 0; i < length; i++) {
//這裡的實現有點依賴了目標的頭字元了,為了簡單忽略
if (content.charAt(i) == 'h' && i + 5 < length
&& content.substring(i, i + 5).equals("href=")) {
int j = i + 6;
boolean match = false;
for (; j < length; j++) {
if (content.charAt(j) == '\"') {
match = true;
break;
}
}
j++;
if (match) {
userOneToOneList.add(content.substring(i, j));
}
i = j;
}
}
}
//消耗時間記錄,為了避免前後程式的幹擾,在具體測試中,一個一個來測試記錄時間
public static void main(String[] args) {
Reg r = new Reg();
r.initContent(8000000);
// 使用OneToOne
long t5 = System.currentTimeMillis();
r.useOneToOneCode();
long t6 = System.currentTimeMillis();
System.out.println("你的程式運行了:" + (int) ((t6 - t5) / 1000) + "秒"
+ ((t6 - t5) % 1000) + "毫秒");
// 使用Regex
long t3 = System.currentTimeMillis();
r.useRegCode();
long t4 = System.currentTimeMillis();
System.out.println("你的程式運行了:" + (int) ((t4 - t3) / 1000) + "秒"
+ ((t4 - t3) % 1000) + "毫秒");
// 使用find
long t1 = System.currentTimeMillis();
r.useCommonCode();
long t2 = System.currentTimeMillis();
System.out.println("你的程式運行了:" + (int) ((t2 - t1) / 1000) + "秒"
+ ((t2 - t1) % 1000) + "毫秒");
}
}
測試過程中,每種方式單獨運行,資料量為8000000字元,資料如下,縱座標單位為毫秒,橫座標單位為次,如圖1.1
圖1.1
當資料量小的時候如800字元到8個字元,使用Regex大約需25毫秒(猜想,所用時間消耗在正則式的解釋中),而其它兩種方式不足1毫秒,若資料量為80000字元,使用Regex大約需45毫秒,而其它兩種方式大約為14毫秒。
通過這次測試,Regex在開發coding中,閱讀和防止出bug上有很大好處,但是其效能依然值得注意。