Einträge in Dateien zählen - Performance-Problem

Status
Nicht offen für weitere Antworten.

muemmel_0811

Bekanntes Mitglied
Hallo zusammen,

ich hab 200 Text-Dateien, deren Größe von 1 kb bis zu 7 MB variieren.
In jeder dieser Dateien steht max. eine Zahl zwischen 1 und 1 Mio pro Zeile, also 1 Integer pro Zeile.
Mein Ziel war es nun, zu zählen, wie oft bspw. die 5 in diesen 200 Dateien vorkommt. An sich auch kein Problem, denn folgender Code tut ja auch was er soll, aber es dauert einfach ewig und mit ewig mein ich, dass nach 1 h gerade mal 3 Dateien eingelesen waren, die jeweils so ca. 3 MB groß waren :( - das schreiben selbst hat dagegen nur ca. 4 Sekunden gedauert...
Code:
public class CountingSeeds extends JFrame{
	private static final long serialVersionUID = 1L;
	Content cntnt = new Content();
	
	CountingSeeds() {
		super();
		setTitle("Seed-Crawler");
		setLayout(new BorderLayout());
		getContentPane().add(cntnt, BorderLayout.CENTER);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		initLaF();
	}
	
	
	public static void main(String[] args) {
		CountingSeeds se = new CountingSeeds();
		se.setSize(600,400);
		se.setLocation(200,200);
		se.setVisible(true);
	}
	
	private void initLaF() {
		try {
			UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
			SwingUtilities.updateComponentTreeUI(this);
			SwingUtilities.updateComponentTreeUI(cntnt);
		}
		catch(Exception c){
		}
	}
	
	private class Content extends JPanel {
		private static final long serialVersionUID = 1L;
		JLabel lbl = new JLabel("Verzeichnis wählen");
		JTextField txtDir = new JTextField();
		JButton btn = new JButton("...");
		JButton btn2 = new JButton("Go");
		JTextArea ta = new JTextArea();
		JScrollPane scr = new JScrollPane();
		JProgressBar bar = new JProgressBar();
		
		Content() {
			double rand = 10.0;
			double[][] size = {{rand,130,300,20,40,20,50,TableLayout.FILL},{rand,25,10,220,20,30,TableLayout.FILL,rand}};
			setLayout(new TableLayout(size));
			add(lbl, "1,1");
			add(txtDir, "2,1");
			btn.addActionListener(new GetDir());
			add(btn, "4,1");
			btn2.addActionListener(new DirScan());
			add(btn2, "6,1");
			scr.setViewportView(ta);
			add(bar, "1,5,6,5");
			add(scr, "1,3,6,3");
		}
	}
	
	class GetDir implements ActionListener{
		public void actionPerformed(ActionEvent ae) {
			JFileChooser fc = new JFileChooser();
			fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
			int option = fc.showOpenDialog(cntnt.txtDir);
			if(option == JFileChooser.APPROVE_OPTION) {
				String pfad = fc.getSelectedFile().getAbsolutePath();
				cntnt.txtDir.setText(pfad);
			}
		}
	}
	
	private class DirScan implements ActionListener {
		public void actionPerformed(ActionEvent ae) {
			
			new Thread() {
				public void run() {
					try{
						Thread.sleep(2000);
						String x = cntnt.txtDir.getText();
						boolean rek = true;
						DirectoryScanner ds = new DirectoryScanner();
						ds.setPfad(cntnt.txtDir.getText());
						ds.setTypen(".txt");
						ds.setRekursiv(rek);
						ArrayList<File> dateien = ds.runDir();
						such(dateien);
					}
					catch(Exception e) {
						e.printStackTrace();
					}
				}
			}.start();
		}
	}
	
	private void such(ArrayList<File> files) {
		String zeile;
		ArrayList<Integer> tmp = new ArrayList<Integer>();
		HashMap<Integer, Integer> seed = new HashMap<Integer, Integer>();
		

		for(File f : files) {
			try {
				BufferedReader rein = new BufferedReader(new FileReader(f));
				cntnt.ta.append("Lese: " + f + "\n");
				while((zeile = rein.readLine()) != null) {
					System.out.println(zeile);
					int zahl = Integer.parseInt(zeile);
					if(tmp.contains(zahl)) {
						Iterator it = seed.entrySet().iterator();
						while(it.hasNext()) {
							Map.Entry e = (Map.Entry)it.next();
							int key = (Integer) e.getKey();
							int val = (Integer) e.getValue();
							if(key == zahl) {
								val = val + 1;
								seed.put(key, val);
							}
						}
					}
					else {
						
						tmp.add(zahl);
						seed.put(zahl, 1);
					}
				}
			}
			catch(Exception e) {
			}
		}
		
		ausgabe(seed);
	}
	
	private void ausgabe(HashMap<Integer, Integer> hm) {
		Iterator it = hm.entrySet().iterator();
		int max = hm.size();



		cntnt.bar.setMinimum(0);
		cntnt.bar.setMaximum(max);
		cntnt.bar.setValue(0);
		cntnt.bar.setStringPainted(true);
		
		try {
			BufferedWriter raus = new BufferedWriter(new FileWriter("C:\\DATEN\\R\\result.txt"));
			cntnt.ta.append("Schreibe result.txt\n\n");
			raus.write("Seed\tAnzahl\n");
			raus.newLine();
			for(int i=0; i<=max; i++) {
				final int a = i;
				SwingUtilities.invokeLater(new Runnable() {
					public void run() {
						cntnt.bar.setValue(a);
					}
				});
				while(it.hasNext()) {
					Map.Entry e = (Map.Entry)it.next();
					int key = (Integer)e.getKey();
					int val = (Integer)e.getValue();
					raus.write(key + "\t" + val);
					raus.newLine();
				}
			}
			raus.close();
			cntnt.ta.append("\n\nFertig");
		}
		catch(Exception e2) {
		}
	}

}

Das Problem scheint ja nun irgendwie beim Überprüfen auf Vorhandensein zu liegen, also ab if(tmp.contains(zahl)), aber wie kann man das besser (also deutlich schneller) lösen? Gibt es besser geeignete Kollektoren dafür oder macht man sowas ganz anders?

Danke und Grüße,
muemmel_0811
 

Ark

Top Contributor
Zeig doch bitte mal ein Stücken von der Datei, die es zu analysieren gilt, und sage anhand dieses Auszugs, was genau du erreichen willst.

Ark
 

Noctarius

Top Contributor
Das ganze GUI Zeugs außen vorgelassen, da ich davon keine Ahnung habe:

Java:
private Map<Integer, Integer> search(List<Files> files) {
	Map<Integer, Integer> seeds = new HashMap<Integer, Integer>();
	
	for (File file : files) {
		try {
			Reader reader = new LineNumberReader(new FileReader(file));
			
			String line = null;
			while ((line = reader.readLine()) != null) {
				Integer seed = Integer.parse(line);
				
				if (seeds.contains(seed)) {
					Integer value = seeds.get(seed) + 1;
					seeds.put(seed, value);
				} else {
					seeds.put(seed, 1);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		} catch (NumberFormatException e) {
			e.printStackTrace();
		}
	}
	
	return seeds;
}
 

Noctarius

Top Contributor
Jo stimmt Google Collections, ich benutz die jeden Tag und denk nicht mal dran *damn* Allerdings bringen diese erst etwas bei extremen Datenmengen, da sie auf hohe Größen ausgelegt sind. Im unteren Größenbereich (unter 50k Einträgen) sind sie nicht schneller eher etwas langsamer als normale Maps und Listen.

Abgesehen davon vermute ich mal, dass ein gewaltiges Problem mit der GUI in dem Code ist. Irgendwas in Richtung "zuoft neuzeichnen" oder etwas in der Richtung, dass die Zeit unnormal in die Höhe treibt. Versuch doch einfach mal das Ganze als reine Konsolenanwendung zu implementieren. Wenn die Zeit dann immer noch so hoch ist, ist definitiv was anderes falsch.
 

muemmel_0811

Bekanntes Mitglied
Super vielen Dank erst mal - ich werde Eure Vorschläge gleich mal testen und mich später wieder melden!

Danke und Grüße vom muemmel_0811
 

muemmel_0811

Bekanntes Mitglied
Hallo Noctarius

vielen, vielen Dank für Deinen Code! Nachdem ich ihn noch etwas angepasst hab, hab ich das Programm gestartet und über die 200 Dateien (insgesamt 206 MB) laufen lassen und bin begeistert - es hat knapp 5 Minuten gedauert, bis alles eingelesen, gezählt und in die Datei geschrieben war :toll:

Es lag also nur an der while-Schleife, die die HashMap durchsucht hat. Gut so, dass ich bereits vergessen hab, wo ich den Schmarrn her hab...
Außerdem hab ich mal den LineNumberReader durch den BufferedReader ersetzt und dann ist das Programm seltsamerweise, kurz vor Ende mit heap-Space-Problemen abgestürzt. Kurz vor Ende heißt, die result.txt war bereits fast fertig geschrieben :bahnhof:

Kann mir noch jemand erklären, warum LineNumberReader besser ist als BufferedReader?

Danke und Grüße,
muemmel_0811
 

Noctarius

Top Contributor
Ich vermute mal, dass der LineNumberReader intern genau so implementiert ist wie er klingt. Zeile lesen, ausgeben, wegschmeissen, nächste Zeile lesen, usw...

Ein Blick in die Sources der Classlib könnte dir vllt Aufschluss geben. Liegen im Installationsordner des JDK in der src.zip :D (grad ma faul ist)

BTW: Find ich 5 Min immer noch ganz schön lange. Aber kann mich auch grad täuschen. Ich hab in der Firma ein Miniprog geschrieben was täglich um die 10k Files parsed und auswertet, allerdings ohne ewige Mapzugriffe, welche das Ganze schon ziemlich verlangsamen könnten.
 

muemmel_0811

Bekanntes Mitglied
Ein Blick in die Sources der Classlib könnte dir vllt Aufschluss geben. Liegen im Installationsordner des JDK in der src.zip :D (grad ma faul ist)
Bist Du Dir sicher, dass ich das verstehen würde bzw. den Unterschied erkennen würde :oops:
Auch egal, es wundert mich halt nur, dass die Heap-Space-Probleme erst beim Schreiben auftreten - zu dem Zeitpunkt ist der BufferedReader doch schon lang aus dem Rennen...

Und was die 5 min betrifft - für mich hat's gereicht :D - war 'ne einmalige Sache, musste also nur etwas performanter als ein Durchlauf dauert x Tage sein.
 

Noctarius

Top Contributor
Vermutlich werden da gerade noch Objekte erstellt und genau da ist der Speicher am Ende. Gib der JVM doch einfach mehr Speicher :)

java -Xmx256M

Ist der Parameter um z.B. 256MB Speicher freizugeben
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
J Markierte Einträge (Dateien) in JList sollen in einen anderen Ordner verschoben werden. Java Basics - Anfänger-Themen 12
N ResultSet auf Einträge überprüfen Java Basics - Anfänger-Themen 5
R While-Loop der die Einträge eines Arrays in umgekehrter Reihenfolge anzeigt Java Basics - Anfänger-Themen 3
C Erste Schritte JComboBox Einträge auf Duplikat prüfen Java Basics - Anfänger-Themen 4
A Einträge aus Tupeln nach Regeln in Liste speichern Java Basics - Anfänger-Themen 8
S CSV auf doppelte Einträge überprüfen Java Basics - Anfänger-Themen 8
K Datentypen Einträge zweier Matrizen vergleichen Java Basics - Anfänger-Themen 4
I Einträge in den Konstruktor Java Basics - Anfänger-Themen 3
S Problem: Array alle Einträge gleich Java Basics - Anfänger-Themen 10
M Erste Schritte JList einträge Java Basics - Anfänger-Themen 1
P Erste Schritte Einträge aus verschachtelter Map chronoligisch ausgeben Java Basics - Anfänger-Themen 5
C JList Einträge nach Datum sortieren Java Basics - Anfänger-Themen 3
T Einträge in jComboBox aus Liste übernehmen Java Basics - Anfänger-Themen 1
S Wie bestehende Excel-Einträge mit neuen Vergleichen (mit Apache POI)? Java Basics - Anfänger-Themen 0
E Array doppelte Einträge Java Basics - Anfänger-Themen 2
S Variablen Array in ArrayList auf doppelte Einträge überprüfen Java Basics - Anfänger-Themen 4
T Alte Einträge im Array werden von neuen überschrieben Java Basics - Anfänger-Themen 5
P Doppelte Einträge in eine List Java Basics - Anfänger-Themen 5
D Javaliste auf gleiche Einträge überprüfen Java Basics - Anfänger-Themen 2
C Doppelte Einträge aus String [] Array entfernen. Java Basics - Anfänger-Themen 5
C Datentypen Array-Einträge überhalb der Array-Länge - welcher Wert? Java Basics - Anfänger-Themen 5
L Erste Schritte Einträge in ArrayList prüfen Java Basics - Anfänger-Themen 4
M Ziffer einträge vergrößern Java Basics - Anfänger-Themen 16
H Einträge aus Array löschen Java Basics - Anfänger-Themen 8
K ArrayList.add() überschreibt vorhandene Einträge. Java Basics - Anfänger-Themen 12
M Gewisse Einträge aus einer ArrayList löschen Java Basics - Anfänger-Themen 3
M doppelte Einträge Emailempfänger... Java Basics - Anfänger-Themen 35
K ArrayList Zugreifen auf Einträge Java Basics - Anfänger-Themen 8
G txt-File als DB>doppelte Einträge verhindern/Suche/... Java Basics - Anfänger-Themen 10
B 2D-Array, gleiche Einträge prüfen Java Basics - Anfänger-Themen 5
F Hiberate-Log-Einträge Java Basics - Anfänger-Themen 2
J Datentypen List - gleiche Einträge bei neuen Objekten Java Basics - Anfänger-Themen 31
Beckenbauer OOP Durch Komma getrennte Einträge in einem String in ein Array oder eine Tabelle schreiben Java Basics - Anfänger-Themen 4
kitz Mehrere Einträge auswerfen? Java Basics - Anfänger-Themen 20
P Doppelte Einträge in mehreren Textfiles finden und ausgeben Java Basics - Anfänger-Themen 8
E Darstellung der Choice Einträge Java Basics - Anfänger-Themen 4
K Datentypen Liste: Einzelne Einträge ändern Java Basics - Anfänger-Themen 2
L Tray-Einträge und dazu passende ActionListener dynamisch erzeugen? Java Basics - Anfänger-Themen 2
J doppelte Einträge in einem Array Java Basics - Anfänger-Themen 7
M Einträge in JComboBox farblich hinterlegen? Java Basics - Anfänger-Themen 2
-horn- Doppelte Einträge entfernen, aus Array, List oder sonstwas Java Basics - Anfänger-Themen 9
G _NUR_ doppelte Einträge in einem Array behalten Java Basics - Anfänger-Themen 3
B Einträge im JList einfügen Java Basics - Anfänger-Themen 9
G doppelte Einträge im String Array löschen Java Basics - Anfänger-Themen 21
V Vector/Arraylist hat nur gleiche Einträge Java Basics - Anfänger-Themen 3
0 ArrayList - doppelte Einträge entfernen? Java Basics - Anfänger-Themen 9
S Methode, um doppelte Einträge in Array zu finden Java Basics - Anfänger-Themen 5
G Wie doppelte Einträge in ComboBox vermeiden ? Java Basics - Anfänger-Themen 9
M Doppelte Einträge in einer datei löschen(nach timestamp)! Java Basics - Anfänger-Themen 4
D Doppelte Einträge einer Liste löschen Java Basics - Anfänger-Themen 6
ARadauer Alle Einträge im Startverzeichnis Java Basics - Anfänger-Themen 5
B 2 ELists vergleichen und doppelte Einträge löschen Java Basics - Anfänger-Themen 11
M einträge farblich hervorheben ? Java Basics - Anfänger-Themen 8
M Vector soll keine doppelten Einträge enthalten! Java Basics - Anfänger-Themen 5
M Einträge einer .txt-Datei in einem TextField ausgeben lassen Java Basics - Anfänger-Themen 8
J Wie kann man im Systempopup einträge machen z.B im Explorer? Java Basics - Anfänger-Themen 6
K mehrere DB Einträge in einem JTable darstellen ?HILFE! Java Basics - Anfänger-Themen 2
G Array-Listen vergleichen und Einträge löschen ? Java Basics - Anfänger-Themen 4
S JList Einträge löschen Java Basics - Anfänger-Themen 3
H .java Dateien in Eclipse einbinden und ausführen Java Basics - Anfänger-Themen 1
I Dateien aus dem Resource Folder laden Java Basics - Anfänger-Themen 2
A Thread XML-Dateien zusammenfügen Java Basics - Anfänger-Themen 11
Buroto Threads Verschiedene .txt Dateien Auf Listen und Verbinden Java Basics - Anfänger-Themen 3
J Dateien lesen und schreiben Java Basics - Anfänger-Themen 5
B Jar Dateien ohne IDE verwenden? Java Basics - Anfänger-Themen 1
A Optimierung eines Programms: Mergen der Dateien Java Basics - Anfänger-Themen 23
A Zwei XML-Dateien Mergen Java Basics - Anfänger-Themen 14
A Input/Output Mehrere Csv-Dateien einlesen Java Basics - Anfänger-Themen 2
LetsSebi Dateien werden nicht in Zip gespeichert Java Basics - Anfänger-Themen 1
J Alle .java Dateien von einem Verzeichnis in eine Zip speichern Java Basics - Anfänger-Themen 2
J Alle Dateien aus einem Verzeichnis laden Java Basics - Anfänger-Themen 10
MiMa log4j als separate Dateien in Schleife? Java Basics - Anfänger-Themen 6
M Scannen von *.txt - Dateien; wo sind der oder die Fehler? Java Basics - Anfänger-Themen 4
A Input/Output Dateien einlesen und ausgeben Java Basics - Anfänger-Themen 7
S Lese- / Schreibfähigkeit von Dateien sicherstellen Java Basics - Anfänger-Themen 1
C "HelloWorld" - Dateien erstellt, aber ist es eine class-Datei? Java Basics - Anfänger-Themen 2
J Java findet plötzlich die Dateien im Projekt nicht mehr. Java Basics - Anfänger-Themen 12
J Dateien in Verzeichnissen rekursiv auflisten wirft Exception Java Basics - Anfänger-Themen 4
L Classpath Alle Dateien im Classpath finden Java Basics - Anfänger-Themen 4
MiMa Formate für Dateien und Pfade? Java Basics - Anfänger-Themen 1
O Datei in mehrere kleine Dateien umwandeln Java Basics - Anfänger-Themen 47
L Richtige Reihenfolge der Dateien Java Basics - Anfänger-Themen 5
CptK Datentypen Text Dateien einlesen Java Basics - Anfänger-Themen 3
J Logging erzeugt zwei dateien.... Java Basics - Anfänger-Themen 7
A Dateien Verschieben Java Basics - Anfänger-Themen 1
M Mehre Dateien parallel kopieren mit Multithreading Java Basics - Anfänger-Themen 8
C Methoden Dateien im Ordner anzeigen Java Basics - Anfänger-Themen 12
J Java-Dateien lassen sich nicht editieren Java Basics - Anfänger-Themen 46
E FTP Dateien hochladen Java Basics - Anfänger-Themen 3
J Probleme beim schreiben von Dateien Java Basics - Anfänger-Themen 5
Korvinus Vergleichen von 2 csv-Dateien Java Basics - Anfänger-Themen 2
I Texte mit Absätzen in Dateien speichern und auslesen Java Basics - Anfänger-Themen 1
M "substring()" mit Dateien und Pfadangaben Java Basics - Anfänger-Themen 5
Voreck Jar Dateien Standart programm ändern Java Basics - Anfänger-Themen 12
K Dateien aus Source-Package verwenden Java Basics - Anfänger-Themen 10
B Dateien aus dem "resource" - Folder kopieren in Verzeichnis Java Basics - Anfänger-Themen 9
B Kopieren von Dateien mit Adminberechtigungen Java Basics - Anfänger-Themen 14
F Threads ftp4j, viele Dateien upload Java Basics - Anfänger-Themen 5
P Einen Ordner mit Dateien hochladen [FTP] Java Basics - Anfänger-Themen 2
X Dateien direkt hintereinander schreiben, Dateiname Java Basics - Anfänger-Themen 25

Ähnliche Java Themen

Neue Themen


Oben