2017-04-12 2 views
-1

Ich habe riesige Textdateien, deren Größe von 500KB bis 500MB reichen kann. Ich habe eine Liste von Schlüsselwörtern, die im Dateiinhalt gefunden werden müssen. Das Nein. von Keywords können bis zu 400.000 sein. Im Moment bin ich mit den folgenden Code, um die Schlüsselwörter in der Datei-InhaltVerbesserte Leistung der Zeichenkettensuche mit Patter.Compile in großen Dateien

public static void main(String[] args) { 
    StringBuilder fileContent = new StringBuilder(); 
    try (BufferedReader reader = new BufferedReader(new FileReader("C:\\Users\\harshita.sethi\\Desktop\\merge\\MNT.txt"))) { 
     String line; 
     while ((line = reader.readLine()) != null) { 
      fileContent.append(line).append("\n"); 
     } 
    } 

    String content = fileContent.toString(); 
    Set<List<String>> keywords = getDbQuery(); // size can be up to 4*10^5 

    for (List<String> key : keywords) { 
     if (checkOccurence(content, key.get(0))) { 
      //Do Somethng 
     } 
    } 
} 

private static boolean checkOccurence(String content, String keyword) { 
    Boolean flag = false; 
    try { 

      Pattern p = Pattern.compile("\\b" + keyword + "\\b", Pattern.CASE_INSENSITIVE); 
      Matcher m = p.matcher(content); 
      flag = m.find(); 


    } catch (PatternSyntaxException ex) { 
     System.out.println("cannot report occrence of " + keyword); 
    } 
    return flag; 
} 

Das Problem ist, mit großen Dateigröße finden es viel Zeit in Anspruch nimmt durch die Datei zu scannen. Ich habe alle möglichen Tests durchgeführt und bin zu dem Schluss gekommen, dass Pattern.Compile den Code langsam macht. Ich habe im Internet gelesen, seit Pattern.compile die Regex kompiliert jedes Mal, wenn die Funktion aufgerufen wird, verbraucht es viel Zeit.

Kann jemand bitte vorschlagen, wie die Leistung dieses Codes verbessern kann, so dass die Suche nach Zeichenfolgen schneller ist.

PS: Ich bin auf Java 6 Version beschränkt.

Bearbeiten -

habe ich versucht, die Zusammenstellung alle Schlüsselwörter vor der for-Schleife, wie wenige Menschen vorgeschlagen. Ich kann sehen, dass es keinen großen Unterschied in der Ausführungszeit des Codes gibt.

Obwohl ich bemerkte, dass durch Entfernen der boundary regex, die Leistung des Codes drastisch geändert. Es dauerte nur wenige Sekunden, um den kompletten Lauf, wo es 8-10 Minuten früher dauerte, zu beenden. Aber indem ich boundary regex entferne, bekomme ich nicht die gewünschte Ausgabe.

Frage - Gibt es eine Möglichkeit, die Leistung mit Grenzen zu verfeinern. Warum hat sich die Performance drastisch verändert?

Mein Ziel (zum Beispiel) ist

  • false zu erhalten, wenn abcd gefunden wird, während abc und
  • true suchen, wenn abc. oder abc, oder abc usw. gefunden wird, während für abc Suche.
+0

Sie können kompilierte Muster speichern und wiederverwenden. – Andrey

+0

Das Schlüsselwort wird bei jeder Iteration geändert. Wie kann ich das Muster vorher zusammenstellen? –

+0

Besser noch, Sie können die Schlüsselwörter kombinieren und nur ein Muster erstellen. –

Antwort

1

Ich würde es vorziehen, Schlüsselwörter zu laden und alle Muster vor dem Suchvorgang zu kompilieren.

Der nächste Schritt zur Verbesserung der Leistung ist die Verwendung der Java 8-Stream-API, mit der Sie den Kompilierungs- und Suchprozess lahmlegen können.

Ich denke, das kann helfen.

+0

haben Ich bin beschränkt, Java 6 zu verwenden. Noch versuche ich, Muster vorher zu kompilieren und zurückzukommen. –

+0

Ich habe den Code wie vorgeschlagen geändert. Siehe das Update der Frage. –

Verwandte Themen