2017-11-04 5 views
-1

Ich habe große Textdatei, die Source-Target-Knoten und threshold.I speichert alle eindeutigen Knoten in HashSet, dann die Kanten basierend auf Benutzer-Schwellenwert filtern und die gefilterten Knoten in separated Hash Set.So möchte ich einen Weg finden, um die Verarbeitung so schnell wie möglich zu tun.Effizientes Lesen und Schreiben von großen Textdatei in Java

public class Simulator { 

static HashSet<Integer> Alledgecount = new HashSet<>(); 
static HashSet<Integer> FilteredEdges = new HashSet<>(); 

static void process(BufferedReader reader,double userThres) throws IOException { 
    String line = null; 
    int l = 0; 

    BufferedWriter writer = new BufferedWriter(new FileWriter("C:/users/mario/desktop/edgeList.txt")); 

    while ((line = reader.readLine()) != null & l < 50_000_000) { 

      String[] intArr = line.split("\\s+"); 

      checkDuplicate(Integer.parseInt(intArr[1]), Integer.parseInt(intArr[2]), Alledgecount); 

      double threshold = Double.parseDouble(intArr[3]); 

      if(threshold > userThres) { 
       writeToFile(intArr[1],intArr[2],writer); 

       checkDuplicate(Integer.parseInt(intArr[1]), Integer.parseInt(intArr[2]), FilteredEdges); 
      } 
     l++; 

    } 

    writer.close(); 

} 

static void writeToFile(String param1,String param2,Writer writer) throws IOException { 

     writer.write(param1+","+param2); 

    writer.write("\r\n"); 

} 

Die Grafik-Klasse tut BFS und schreibt die Knoten in getrennten file.I die Verarbeitung ohne getan haben einige Funktionalitäten und die Zeiten sind unten.

Timings mit 50 Millionen Zeilen liest in Prozess()

without calling BFS(),checkDuplicates,writeAllEdgesToFile() -> 54s 
without calling BFS(),writeAllEdgesToFile() -> 50s 
without calling writeAllEdgesToFile() -> 1min 

Timings mit 300 Millionen Zeilen liest in Prozess()

without calling writeAllEdges() 5 min 
+2

Sie können Millionen von Zeilen pro Sekunde mit 'BufferedReader.readLine()' lesen. Das sollte ausreichen. Es gibt keinen Grund zu glauben, dass der Versuch, es zu multi-threading, es schneller machen wird. Die Festplatte ist nicht multi-threaded. – EJP

+0

Wenn Sie Hilfe bei der Optimierung Ihres Codes haben möchten, wäre mein Ratschlag, nicht zu Multi-Threading zu springen, was höchstwahrscheinlich nicht die richtige Antwort ist (zumindest nicht die Art, wie Sie es tun, da alle Threads die gleiche Datei lesen und tun die gleiche Arbeit, auf den gleichen Daten). Stellen Sie Ihre Monothread-Lösung stattdessen bereit, ohne Schlüsselelemente wie checkDuplicate-Methoden zu entfernen und erklären Sie, was die Datei enthält und was der Prozess tun soll. –

+0

ok ich habe Kommentare hinzugefügt. –

Antwort

3

Lesen eine Datei auf CPU-Kern nicht nur abhängen.
E/A-Vorgänge in einer Datei werden durch physikalische Einschränkungen von klassischen Datenträgern eingeschränkt, die im Gegensatz zum CPU-Kern keine parallelen Vorgänge ausführen können.

Was Sie tun können, ist für IO-Operationen mit einem Gewinde und andere (n) für die Datenverarbeitung, aber es macht nur Sinn, wenn Datenverarbeitung lang genug ist relevant, um ein Thread für diese Aufgabe zu erstellen, wie Thread s a haben Kosten in Bezug auf CPU-Planung.

+0

Ich habe es 10 Stunden lang ausgeführt, um die Datei zu lesen, die Daten zu filtern und dann in eine andere Datei zu schreiben, ABER es wird nicht beendet. Ich habe die Textdatei geöffnet und festgestellt, dass nur 7 Millionen Zeilen in die Datei geschrieben wurden Ich weiß nicht, was es falsch läuft –

+0

Gute Erklärungen, Sir. Schade, dass die OP nicht versteht, wie man richtige Fragen stellt ... und eine neue aufstellt, anstatt mit Leuten zu arbeiten, um Dinge zum Laufen zu bringen. – GhostCat

+0

Damit die Dinge funktionieren, muss ich eine Antwort darauf bekommen, was ich falsch mache, oder ein Beispielcode, um besser zu verstehen, wie es geht. –

2

Es kann sehr schwierig sein, ein Java-Multithread-Programm korrekt auszuführen. Es erfordert ein tiefgehendes Verständnis von Dingen wie Synchronisierungsproblemen usw. Ohne das Wissen/die Erfahrung, die notwendig sind, wird es Ihnen schwer fallen, nach Fehlern zu suchen, die manchmal auftreten, aber nicht zuverlässig reproduzierbar sind.

Also, bevor Multi-Threading versuchen, herauszufinden, ob es gibt einfachere Wege eine akzeptable Leistung zu erreichen:

den Teil des Programms finden, dass die Zeit in Anspruch nimmt!

Erste Frage: ist es I/O oder CPU? Sehen Sie sich den Task-Manager an. Bezieht sich Ihr Singlethread-Programm auf einen Kern (z. B. CPU nahe 25% auf einem 4-Core-Rechner)? Wenn es weit darunter liegt, dann muss I/O der begrenzende Faktor sein, und das Ändern Ihres Programms wird wahrscheinlich nicht viel helfen - kaufen Sie ein schnelleres HD. (In einigen Situationen kann die Software-Stil zu tun I/O kann die Hardware-Leistung beeinflussen, aber das ist selten.)

Wenn CPU ist, einen Profiler verwenden, z.B. die JVisualVM im JDK enthalten, um die Methode zu finden, die den größten Teil der Laufzeit beansprucht und über Alternativen nachdenkt. Ein Kandidat könnte der sein, der einen regulären Ausdruck verwendet. Sie sind langsam, besonders wenn der Ausdruck nicht vorher zu einem Pattern kompiliert wird - aber das ist nichts weiter als eine Vermutung, und der Profiler wird Ihnen wahrscheinlich einen sehr unterschiedlichen Ort erzählen.

+0

Upvote für den Kern von diesem: Profiling und root Ursache Bestimmung. – GhostCat

Verwandte Themen