2012-12-14 63 views
1

我已經創建了一個應用程序來處理日誌文件,但我有一些瓶頸時,文件的數量=〜20高效的文本處理的Java

問題來自哪個平均需要一秒鐘左右,以一個特定的方法大致完成,正如你可以imagime這是不實際的時候需要做的> 50倍

private String getIdFromLine(String line){ 
    String[] values = line.split("\t"); 
    String newLine = substringBetween(values[4], "Some String : ", "Value="); 
    String[] split = newLine.split(" "); 
    return split[1].substring(4, split[1].length()); 
} 



private String substringBetween(String str, String open, String close) { 
     if (str == null || open == null || close == null) { 
      return null; 
     } 
     int start = str.indexOf(open); 
     if (start != -1) { 
      int end = str.indexOf(close, start + open.length()); 
      if (end != -1) { 
       return str.substring(start + open.length(), end); 
      } 
     } 
     return null; 
    } 

一條線來自於一個文件,該文件是非常有效的閱讀,所以我不覺得有必要給它發佈該代碼,除非有人問。

反正有沒有改善這個perofmrance?

感謝您的時間

+0

這將是有益或許,如果您還提供一個例子正則表達式在這裏被解析的一行......會使代碼更易於閱讀。 –

+0

我很想去,但它是敏感的工作數據 - 不知道我可以明智地改變它 – Biscuit128

+0

以及你可以創建一個虛擬的,像'xxx:aaa-> bbb,ccc dd cc ee'。我認爲更高效的算法將取決於你試圖解析的數據類型。 –

回答

2

我會嘗試使用正則表達式。

+1

正則表達式不是最好的表現方式 – Andremoniy

+1

你爲什麼這麼想?我會給他們一個機會。無論如何,測試和比較是獲得最佳結果的最佳方式。 – Behnil

0

我會建議使用VisualVM找到瓶頸之前oprimisation。
如果您在應用程序中需要性能,則無論如何都需要進行性能分析。

由於優化我會做一個自定義的循環來替代你substringBetween方法,擺脫多的indexOf調用

2

有幾件事情都可能存在問題:

  1. 無論你是否意識到,你使用正則表達式。 String.split()的論點被視爲正則表達式。使用String.indexOf()幾乎可以肯定是找到所需字符串的特定部分的更快方法。正如HRgiger指出的那樣,番石榴的分離器是一個不錯的選擇,因爲它確實如此。

  2. 你正在分配一堆你不需要的東西。根據您的線路的時間長短,您可能會創建一大堆您不需要的額外String s和String[](以及垃圾收集它們)。避免String.split()的另一個原因。

  3. 我還建議使用String.startsWith()String.endsWith(),而所有的這些東西,你與indexOf()做的,如果只有一個事實,即它會更容易閱讀。

+0

我同意你的意見。 +1 – Andremoniy

1

此代碼的主要問題之一是「split」方法。 比如這一個:

private String getIdFromLine3(String line) { 
     int t_index = -1; 
     for (int i = 0; i < 3; i++) { 
      t_index = line.indexOf("\t", t_index+1); 
      if (t_index == -1) return null; 
     } 
     //String[] values = line.split("\t"); 
     String newLine = substringBetween(line.substring(t_index + 1), "Some String : ", "Value="); 
//  String[] split = newLine.split(" "); 
     int p_index = newLine.indexOf(" "); 
     if (p_index == -1) return null; 
     int p_index2 = newLine.indexOf(" ", p_index+1); 
     if (p_index2 == -1) return null; 
     String split = newLine.substring(p_index+1, p_index2); 

//  return split[1].substring(4, split[1].length()); 
     return split.substring(4, split.length()); 
    } 

UPD:它可能快3倍。

+0

爲什麼你認爲這會快3倍? – gk5885

+0

性能測試顯示它... – Andremoniy

+0

鑑於您沒有他的輸入數據,您似乎不太可能以任何類似於原始海報遇到的問題的方式測試了您的實現。 – gk5885

0

你能繼續嘗試正則表達式和後效果好嗎只是比較:

Pattern p = Pattern.compile("(Some String :)(.*?)(Value=)"); //remove first and last group if not needed (adjust m.group(x) to match 

@Test 
public void test2(){ 
    String str = "Long java line with Some String : and some object with Value=154345 "; 
    System.out.println(substringBetween(str));  
} 

private String substringBetween(String str) {  
    Matcher m = p.matcher(str); 
    if(m.find(2)){ 
     return m.group(2);   
    }else{ 
     return null; 
    } 
} 

如果這是更快的發現,結合了功能