2015-05-20 62 views
1

我有一個需求,在這個需求中,我必須掃描特定關鍵字匹配的某些文件。我的關鍵字列表大小約爲40000,我的所有文件大約有4000行。此外,該關鍵字不應該在文件中註釋,因此我也必須照顧評論。我寫的關於關鍵字出現的代碼大約需要5分鐘才能完成每個文件。我不知道我可以做些什麼來減少執行時間。 代碼如下所示。如何減少下列程序的執行時間

for (File fl : files) { 
     flag = false; 
     content = FileUtils.readFileToString(fl); 
     System.out.println(fl.getName()); 
     fileName = fl.getName(); 

     // Object Keywords scanning 
     keywords = null; 
     keywords = findKeywordType(fileName); 
     if (keywords != null) { 
      Boolean keywordCount = false; 
      for (String[] key : keywords) { 
       key[0] = key[1]; 
      } 
      for (String[] key : keywords) { 
       Boolean check = false; 
       if (content.contains(key[0])) { 
        if (content.contains(key[3] + ".")) { 
         check = true; 
        } 
        if (check) { 
         continue; 
        } 
        if (content.contains(key[3])) { 
         keywordCount = FindOccurence(fl, key[0], key[3]); 
         if (keywordCount) { 
          System.out.println("Writing keywords"); 
          objKwm = new ObjectKeywordMaster(); 
          objKwm.setObjectName(key[0]); 
          objKwm.setObjectType(key[1]); 
          objKwm.setObjectOwner(key[2]); 
          objKwm.setDependentObjectName(key[3]); 
          objKwm.setDependentObjectType(key[4]); 
          objKwm.setDependentObjectOwner(key[5]); 
          objKw.getObjectKeywords().add(objKwm); 

         } 
        } 
       } 
      } 
     } 

FindOccurrence方法的代碼是

private static Boolean FindOccurence(File fl, String objectName, String keyword) throws IOException { 
     int startComment = 0; 
     int endComment = 0; 
     Boolean objCheck = false; 
     Boolean keyCheck = false; 
     Boolean check = false; 
     List line = FileUtils.readLines(fl); 
     int fileLength = line.size(); 
     int objCount = 0; 
     int keyCount = 0; 
     loop: 
     for (int j = 0; j < fileLength; j++) { 
      if (line.get(j).toString().contains("/*")) { 
       startComment = j; 
      } 
      if (line.get(j).toString().contains("*/")) { 
       endComment = j; 
      } 
      if (line.get(j).toString().contains(objectName)) { 
       objCheck = false; 
       Pattern p = Pattern.compile("\\b" + objectName + "\\b"); 
       Matcher m = p.matcher(line.get(j).toString()); 
       while (m.find()) { 
        objCheck = true; 
        objCount++; 
       } 
       if (objCheck) { 
        if (line.get(j).toString().contains("#")) { 
         int objIndex = line.get(j).toString().indexOf(objectName); 
         int commentIndex = line.get(j).toString().indexOf("#"); 
         if (objIndex > commentIndex) { 
          objCount--; 
         } 

        } else { 
         if (line.get(j).toString().contains("--")) { 
          int objIndex = line.get(j).toString().indexOf(objectName); 
          int commentIndex = line.get(j).toString() 
            .indexOf("--"); 
          if (objIndex > commentIndex) { 
           objCount--; 
          } 
         } 
        } 
        if ((j >= startComment && j <= endComment)||(j >= startComment && endComment==0)) { 
         objCount--; 
        } 
       } 
      } 

      if (line.get(j).toString().contains(keyword)) { 
       keyCheck = false; 
       Pattern p = Pattern.compile("\\b" + keyword + "\\b"); 
       Matcher m = p.matcher(line.get(j).toString()); 
       while (m.find()) { 
        keyCheck = true; 
        keyCount++; 
       } 
       if (keyCheck) { 
        if (line.get(j).toString().contains("#")) { 
         int objIndex = line.get(j).toString().indexOf(keyword); 
         int commentIndex = line.get(j).toString().indexOf("#"); 
         if (objIndex > commentIndex) { 
          keyCount--; 
         } 

        } else { 
         if (line.get(j).toString().contains("--")) { 
          int objIndex = line.get(j).toString().indexOf(keyword); 
          int commentIndex = line.get(j).toString() 
            .indexOf("--"); 
          if (objIndex > commentIndex) { 
           keyCount--; 
          } 
         } 
        } 
        if ((j >= startComment && j <= endComment)||(j >= startComment && endComment==0)) { 
         keyCount--; 
        } 
       } 
      } 
      if(objCount > 0 && keyCount >0){ 
       check = true; 
       break loop; 
      } else 
       check = false; 
     } 
     return check; 
    } 
} 

我有兩個發現存在於同一個列表兩個關鍵字的occurence。請提出一些方法,以便我可以縮短執行時間。

+0

是否可以減少關鍵字列表的大小?例如,是否包含區分大小寫的關鍵字(The,THE,...)? – User404

+1

你應該使用更好的算法。你的實現*非常*天真。例如。 https://en.wikipedia.org/wiki/Aho-Corasick_algorithm的一些實現可以大大加快您的程序。 – llogiq

+0

這些關鍵字來自數據庫,我不能減小大小或忽略任何關鍵字 –

回答

0

1)在開始查找任何關鍵字之前,請準備文件內容:刪除評論......。

2)用文字分割文件內容。

3)不要爲每個關鍵字循環:使用一個存儲所有關鍵字的Set。

+0

非常好的建議 – Ridcully

+0

我按照建議閱讀文件後立即刪除了評論。此外,關鍵字數組有6列,所以它給每一行唯一唯一。時間相對減少,但仍然不是很快。我只有4萬個關鍵字,它不應該花很長時間。 –

+0

我不明白關於關鍵字數組列的statemernts。如果您循環遍歷每個文件的所有關鍵字,則您的成本爲O(k * f),其中「k」爲文件的關鍵字數量和「f」數量。如果您將關鍵字存儲在集合中,則成本爲O(log(k)* f)。對於40.000個關鍵字,這大約快2500倍。 –