JEditorPane langsam großes HTML

Curry

Aktives Mitglied
Moin Moin!

Ich habe in einem TableModel ein Feld "Authors" mit Autorennamen von Artikeln. Für jeden Artikel (= Tabellenzeile) gibt es einen Wert für das Feld "Authors" nach dem folgenden Muster:

"Müller P, Hansen TH, Mayer H, Schmidt K, Ludwig J".

Ich gebe in einem JEditorPane eines JDialogs eine Statistik aus, bei wievielen Artikeln ein Autor beteiligt war. Also z.B.
#################
Ludwig J | 10
Schmidt K | 4
Mayer H | 4
Hansen TH |2
Müller P |1
Franzen G | 1
Claasen | 1
#################

Das funktioniert mit dem unten stehenden Code auch schon recht gut, allerdings dauert es recht lange. Hat jemand eine gute Idee wie ich die Performance deutlich steigern kann? Ich habe knapp 1000 Artikel in der Tabelle und im Schnitt sind es so 5 bis 8 Autoren.

In Worten beschrieben funktioniert der Code so: Ich gehe jeden Artikel (= Paper) aus dem TableModel durch, lese dessen Autorenliste (ein String) aus und splitte diese Anhand der Kommata (jetzt ein String[]). Nun erstelle ich eine HashMap mit dem Autorennamen als Key und der Häufigkeit dessen vorkommens als Value. Wenn ein Autor bereits in der HashMap ist, dann wird sein Value um 1 erhöht. Zum Schluss wird eine HTML-Tabelle aus der HashMap erstellt.

Dieser Prozess nimmt einiges an Zeit in Anspruch. Wie geht es schneller? ;-)

Java:
int n = model.getRowCount();

System.out.println("table rows = " + n);

ArrayList<Paper> papers = model.getPapers();
HashMap<String, Integer> stats = new HashMap<String, Integer>();

for (int i = 0; i < n; i++) {
	String authors = papers.get(i).getAuthorList();
	String[] array = authors.split(",");
	for (int j = 0; j < array.length; j++) {
		String author = array[j].trim().toUpperCase();

		int count = stats.containsKey(author) ? stats.get(author) : 0;
		stats.put(author, count + 1);

	}
}

System.out.println("number of authors = " + stats.size());

for (Map.Entry e : stats.entrySet()) {
	sb.append("<tr><td>" + e.getKey() + "</td><td>" + e.getValue() + "</td></tr>");
}
 
Zuletzt bearbeitet von einem Moderator:

Marco13

Top Contributor
Wenn man
Java:
int count = stats.containsKey(author) ? stats.get(author) : 0;
stats.put(author, count + 1);
ersetzt durch sowas wie
Java:
Integer value = stats.get(author);
stats.put(author, value==null?1:value+1);
spart man sich einen Lookup, aber das sollte vernachlässigbar sein.

Ein weiterer möglicher Tipp wäre, zu versuchen, das split(",") durch indexOf/substring-Gefrickel zu ersetzen - könnte schneller sein.

Aber irgendwie kann ich mir kaum vorstellen, dass 1000 Artikel so lange dauern - sicher, dass DAS der Flaschenhals ist?
 
N

nillehammer

Gast
Java:
String author = array[j].trim().toUpperCase();
Ich glaube zwar auch nicht, dass DAS der Flaschenhalst ist, aber das toUpperCase kannst Du Dir vielleicht sparen. In Deiner Beispielausgabe sind die Namen jedenfalls auch nicht geuppercased.

Und um Marco's Tipp mit dem substring statt Split zu verfeinern. Das ist genau das, was der StringTokenizer macht. Den könnte man also auch noch ausprobieren.

Aber wie immer, keine Optimierung ohne Kontrolle, also um die entsprechenden Codeabschitte mal Zeitstempel setzen (System.currentTimeMillis), Differenzen bilden und mit System.out.printlin ausgeben lassen.
 

Curry

Aktives Mitglied
Moin Moin!

Danke für eure Antworten!!

Ihr habt recht, der von mir kopierte Code-Teil ist nicht das Problem. Anbei der komplette Code und nachfolgend die Zeiten. Der Flaschenhals ist demnach das setText(str) in die JEditorPane in Zeile 81. Gibt's da etwas das ich optiemieren könnte?

Java:
package view.dialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JFrame;
import model.LibraryTableModel;
import model.Paper;

public class AuthorStatisticsDialog extends HTMLDialog {

	private LibraryTableModel model;

	long time_1, time_2, time_3, time_4, time_5, time_6, time_7, time_8;

	public AuthorStatisticsDialog(JFrame frame, String title, boolean modal, LibraryTableModel model) {
		super(frame, title, modal);
		
		time_1 = System.nanoTime();
		
		this.model = model;

		createStatistics();

		time_8 = System.nanoTime();

		System.out.println("Duration 4 = " + (time_4 - time_1));
		System.out.println("Duration 5 = " + (time_5 - time_1));
		System.out.println("Duration 6 = " + (time_6 - time_1));
		System.out.println("Duration 7 = " + (time_7 - time_1));
		System.out.println("Duration 8 = " + (time_8 - time_1));
	}

	private void createStatistics() {

		StringBuilder sb = new StringBuilder();

		sb.append("<html><head><style type=\"text/css\">table { font-size: 10px; font-family: sans-serif; } th { text-align: left; background-color: #cccccc; } </style></head><body>");
		sb.append("<table border=\"0\" cellspacing=\"1\" cellpadding=\"1\">");

		sb.append("<thead><tr><th>Author</th><th>Anzahl</th></tr></thead>");
		sb.append("<tbody>");

		int n = model.getRowCount();

		time_2 = System.nanoTime();

		System.out.println("n = " + n);

		ArrayList<Paper> papers = model.getPapers();
		HashMap<String, Integer> stats = new HashMap<String, Integer>();

		time_3 = System.nanoTime();

		for (int i = 0; i < n; i++) {
			String authors = papers.get(i).getAuthorList();
			String[] array = authors.split(",");
			for (int j = 0; j < array.length; j++) {
				String author = array[j].trim().toUpperCase();

				int count = stats.containsKey(author) ? stats.get(author) : 0;
				stats.put(author, count + 1);

			}
		}

		System.out.println("entries = " + stats.size());

		time_4 = System.nanoTime();

		for (Map.Entry e : stats.entrySet()) {
			sb.append("<tr><td>" + e.getKey() + "</td><td>" + e.getValue() + "</td></tr>");
		}

		time_5 = System.nanoTime();

		sb.append("</tbody></table></body></body></html>");

		String str = sb.toString();
		time_6 = System.nanoTime();
		ep.setText(str);
		time_7 = System.nanoTime();
		ep.setCaretPosition(0);
	}
}

########################################
Hier die Zeiten:
Duration 4 = 23465678
Duration 5 = 31601539
Duration 6 = 31650569
Duration 7 = 6310137191
Duration 8 = 6310223376
########################################

Java:
package view.dialog;

import java.awt.Dimension;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import org.jdesktop.swingx.JXEditorPane;

public class HTMLDialog extends JDialog {

	protected JScrollPane sp;
	protected JXEditorPane ep;

	public HTMLDialog(JFrame frame, String title, boolean modal) {
		super(frame, title, modal);
		this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
		ep = new JXEditorPane("text/html", "");
		ep.setEditable(false);
		ep.setPreferredSize(new Dimension(640, 480));
		sp = new JScrollPane(ep);
		add(sp);
		pack();
		setLocationRelativeTo(null);
	}
}
 

Marco13

Top Contributor
Ist etwas schwer zu erkennen, wegen
System.out.println("Duration 8 = " + (time_8 - time_1));

Vielleicht die Zeiten mal immer direkt ausgeben
Java:
long before, after;

before = System.nanoTime();
machWas();
after = System.nanoTime();
System.out.println("Duration X: "+((after-before)/1e6)+"ms");
Ist natürlich SEHR ungenau im Vergleich zu einem Profiler, aber vielleicht erkennt man was...
 

schalentier

Gesperrter Benutzer
Wenn ich das richtig sehe, geht hier die Zeit drauf:
Code:
time_6 = System.nanoTime();
ep.setText(str);
time_7 = System.nanoTime();

Also beim Setzen des Textes, nicht beim Erzeugen.

Wie lang ist [c]str[/c]?
 

Curry

Aktives Mitglied
Danke schonmal für eure Antworten!

Ich habe mein Programm noch der Anleitung http://http://java-sl.com/JEditorPanePerformance.html umgebaut. Eigentlich meine ich alles beachtet zu haben, aber die folgenden Zeilen sagen etwas anderes:

[WR]Zeit - Zusammenbau der HashMap: 14.849536ms
Zeit - StringBuilder.toString(): 0.042518ms
Zeit - JEditorPane.setText(): 6396.420973ms; Textlänge = 96273 Zeichen
Zeit - JEditorPane.setCaretPosition(): 0.073928ms[/WR]

Das Beispiel aus dem Programm habe ich nachgebaut und die Methode "getTestText()" so verändert, dass sie den Text, der auch in meinem eigentlichen Programm gesetzt werden soll, setzt. In diesem Testprogramm funktioniert das auch super schnell. Ich weiss leider nicht, woran es liegt, dass im eigentlichen Programm derselbe Text so langsam gesetzt wird. Hat von euch jemand eine Idee wo das Problem ist?

Java:
package view.dialog;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import model.LibraryTableModel;
import model.Paper;
import view.editor.MyEditorKit;

public class AuthorStatisticsDialog extends JDialog {

	private LibraryTableModel model;
	long before, after;

	public AuthorStatisticsDialog(JFrame frame, String title, boolean modal, LibraryTableModel model) {
		this.model = model;
		init();
	}

	private void init() {
		setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

		final JEditorPane ep = new JEditorPane("text/html", "");
		ep.setEditorKit(new MyEditorKit());
		ep.setEditable(false);
//		ep.setPreferredSize(new Dimension(640, 480));
		final JScrollPane sp = new JScrollPane(ep);
		ep.getDocument().putProperty("i18n", Boolean.TRUE);
		setText(ep);
		add(sp);
//		pack();
		setBounds(0, 0, 640, 480);
		setLocationRelativeTo(null);
	}

	private void setText(JEditorPane editor) {

		StringBuilder sb = new StringBuilder();

		sb.append("<html><head><style type=\"text/css\">table { font-size: 10px; font-family: sans-serif; } th { text-align: left; background-color: #cccccc; } </style></head><body>");
		sb.append("<table border=\"0\" cellspacing=\"1\" cellpadding=\"1\">");

		sb.append("<thead><tr><th>Author</th><th>Anzahl</th></tr></thead>");
		sb.append("<tbody>");

		int n = model.getRowCount();

		before = System.nanoTime();
		ArrayList<Paper> papers = model.getPapers();
		HashMap<String, Integer> stats = new HashMap<String, Integer>();

		for (int i = 0; i < n; i++) {
			String authors = papers.get(i).getAuthorList();
			String[] array = authors.split(",");
			for (int j = 0; j < array.length; j++) {
				String author = array[j].trim().toUpperCase();

				int count = stats.containsKey(author) ? stats.get(author) : 0;
				stats.put(author, count + 1);

			}
		}
		after = System.nanoTime();
		System.out.println("Zeit - Zusammenbau der HashMap: " + ((after - before) / 1e6) + "ms");

		for (Map.Entry e : stats.entrySet()) {
			sb.append("<tr><td>" + e.getKey() + "</td><td>" + e.getValue() + "</td></tr>");
		}

		sb.append("</tbody></table></body></body></html>");

		before = System.nanoTime();
		String str = sb.toString();
		after = System.nanoTime();
		System.out.println("Zeit - StringBuilder.toString(): " + ((after - before) / 1e6) + "ms");

		before = System.nanoTime();
		editor.setText(str);
		after = System.nanoTime();
		System.out.println("Zeit - JEditorPane.setText(): " + ((after - before) / 1e6) + "ms; Textlänge = " + str.length() + " Zeichen");

		before = System.nanoTime();
		editor.setCaretPosition(0);
		after = System.nanoTime();
		System.out.println("Zeit - JEditorPane.setCaretPosition(): " + ((after - before) / 1e6) + "ms");
	}
}
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Relative Pfadangabe in JEditorPane zur lokalen Datei Allgemeine Java-Themen 2
A Auswahl eines JEditorPane das Sich in einem JScrollPanel Befindet Allgemeine Java-Themen 2
A jEditorPane Html Datei öffnen (code) Allgemeine Java-Themen 3
T TextArea, JTextPane, JEditorPane Allgemeine Java-Themen 11
StrikeTom Swing JEditorPane automatischer Umbruch Allgemeine Java-Themen 4
W CSS in JEditorPane Allgemeine Java-Themen 32
I Teilweise falsche Darstellung jap. Zeichen im JEditorPane mit RTFEditorKit aus RTF-Datei Allgemeine Java-Themen 5
S Swing mit JEditorPane per HTML auf Bilder in JAR zugreifen. Allgemeine Java-Themen 3
E JTextArea / JEditorPane + Text formatieren Allgemeine Java-Themen 3
T JavaScript aus HTML im JEditorPane ausführen? Allgemeine Java-Themen 5
X Ausgabe auf JEditorPane Allgemeine Java-Themen 5
Iron Monkey JEditorPane mit Refresh von Meta Allgemeine Java-Themen 7
S ImageTag in JEditorPane Allgemeine Java-Themen 2
R JTextPane (JEditorPane) ignoriert JScrollPane Allgemeine Java-Themen 5
U JEditorPane & copy'n'paste Allgemeine Java-Themen 34
O breite des inhalts eines jeditorpane Allgemeine Java-Themen 2
G JEditorPane Zeilenumbruch Allgemeine Java-Themen 1
G JEditorPane will nicht scrollen! Allgemeine Java-Themen 2
D Suchfunktion innerhalb Jeditorpane Allgemeine Java-Themen 6
G JEditorPane: angezeigter Text Allgemeine Java-Themen 21
D Jeditorpane + einlesen ausserhalb des Jar Allgemeine Java-Themen 4
T JApplet - JEditorPane gegen JPanel tauschen Allgemeine Java-Themen 2
T JEditorPane oder JTextPane Applets und Flash anzeigen Allgemeine Java-Themen 7
T JEditorPane aktualisieren Allgemeine Java-Themen 14
V Hyperlink mit JEditorPane Allgemeine Java-Themen 40
V Hyperlink hervorheben mit Hilfe von der Klasse JEditorPane Allgemeine Java-Themen 7
S JEditorPane / JScrollPane und nach unten scrollen Allgemeine Java-Themen 3
R JDK installieren OpenJDK-Aufruf sehr langsam Allgemeine Java-Themen 4
K Arbeitsspeicher wird langsam voll Allgemeine Java-Themen 6
E JavaFX RMI extrem langsam wenn Server nicht läuft Allgemeine Java-Themen 5
Thallius String erzeugen sehr langsam Allgemeine Java-Themen 16
S JNLP startet seit 1.8.0_31 sehr langsam + Windows-Systemverzeichnis Allgemeine Java-Themen 3
P Eclipse langsam/unbrauchbar bei größeren Quelldateien? Allgemeine Java-Themen 8
W Threads NullPointer: Konstruktor "zu langsam"? Allgemeine Java-Themen 3
M Externe Jar sehr langsam Allgemeine Java-Themen 23
J Laden von JAR Files geht ohne ADMIN Rechte sehr langsam Allgemeine Java-Themen 6
H Kopieren sehr langsam Allgemeine Java-Themen 5
B Cipher.getInstance Aufruf sehr langsam Allgemeine Java-Themen 2
B util.Timer zu langsam? Allgemeine Java-Themen 3
W Java Applet läuft langsam Allgemeine Java-Themen 2
N Liste mit Map abgleichen extrem langsam Allgemeine Java-Themen 6
C Darstellung der Liste bei vielen Daten extrem langsam Allgemeine Java-Themen 11
B JavaPanels langsam schliessen und öffne Allgemeine Java-Themen 6
L Java Debugmodus ist unerträglich langsam! Allgemeine Java-Themen 30
L Java 1.5 - Anwendung unter 1.6 JRE sehr langsam geworden Allgemeine Java-Themen 8
H JID3 + vdheide schreiben zu langsam Allgemeine Java-Themen 11
M String zusammensetzen->sehr langsam Allgemeine Java-Themen 3
T ObjectOutputStream#writeObject() zu langsam. Allgemeine Java-Themen 13
N Berechnungsthreads zu langsam. Allgemeine Java-Themen 2
G Java Socket langsam unter Linux Allgemeine Java-Themen 21
T String.split() - viel zu langsam Allgemeine Java-Themen 9
T [SVNKit] Commit sehr langsam. Allgemeine Java-Themen 7
W sin und cos bei hohen Werten extrem langsam Allgemeine Java-Themen 12
G Domainen crawlen & Domainnamen listen -> LANGSAM! Allgemeine Java-Themen 19
M Performance enorm langsam Allgemeine Java-Themen 26
H java.util.Vector langsam ? Allgemeine Java-Themen 5
T Jtree zu langsam beim klappen Allgemeine Java-Themen 8
F JAVA Applikationen starten sehr langsam Allgemeine Java-Themen 14
D Datei öffnung sehr langsam Allgemeine Java-Themen 17
H Verschlüsselungsprogramm zu langsam Allgemeine Java-Themen 12
G Neue Warenwirtschaft aber sehr langsam! Allgemeine Java-Themen 3
T Bilder bearbeiten unglaublich langsam Allgemeine Java-Themen 9
H Entpacken sehr langsam Allgemeine Java-Themen 10
C Thread zu langsam ==> kann doch nicht sein oder? Allgemeine Java-Themen 9
R Double Buffering zu langsam Allgemeine Java-Themen 11
D ganze packete importieren --> langsam? Allgemeine Java-Themen 9
G Funktion, die langsam wächst Allgemeine Java-Themen 7
Seikuassi Input/Output ZipOutputStream erzeugt zu großes .zip-Archiv Allgemeine Java-Themen 3
E Sonderzeichen nicht setzbar: Großes Problem bei Programmierung unter Linux Mint mit Virtual Box Allgemeine Java-Themen 5
B Großes Projekt "gut" schreiben Allgemeine Java-Themen 22
R Großes Hash-Set erzeugen Allgemeine Java-Themen 12
V aus mehreren jar files, ein großes basteln Allgemeine Java-Themen 22
T Datenstruktur für großes Netz Allgemeine Java-Themen 2
G Großes Programm - Wie Strukturieren? Allgemeine Java-Themen 19
A Großes Problem mit dem Lesen großer Datenmengen Allgemeine Java-Themen 16

Ähnliche Java Themen

Neue Themen


Oben