Performanzprobleme - Code schneller machen

Status
Nicht offen für weitere Antworten.

feuervogel

Mitglied
Hallo,

ich habe ein Problem mit einer Klasse - sie ist zu langsam. Mir fällt momentan nicht ein, wie ich sie schneller machen könnte. Es geht um folgendes: Ich will ein Wort in seine Teilworte zerlegen - also "Prüfungszeitstressfaktor" in Prüfung zeit stress faktor.

Dazu habe ich die Klasse CompoundSplitter, die eine Methode "splitOnce" besitzt, die an der wahrscheinlichsten Stelle trennt, im Obigen Fall ist vor "faktor". Danach wird erneut versucht zu trennen, und zwar "Prüfungszeitstress" und "faktor". "faktor" kann nicht weiter getrennt werden, aber prüfungszeitstress in prüfungszeit und stress usw usf.

das ganze sieht dann so aus:

Java:
protected List<String> iterativeSplit(String word){
		
		
		List<String> tlist1 = new LinkedList<String>();
		List<String> tlist2 = new LinkedList<String>();
		List<String> tlist3 = new LinkedList<String>();
		tlist1.add(word);
		boolean splitted;
		while(true){
			splitted = false;
			for(String tempword : tlist1){
				
				tlist3 = this.splitOnce(tempword);
				if(tlist3.size() > 1){
					
					splitted = true;
					
				}
				tlist2.addAll(tlist3);
			
			}
			
			if(splitted == false){
				
				return tlist1;
				
			}else{
				
				tlist1.clear();
				tlist1.addAll(tlist2);
				tlist2.clear();
				
			}
			
		}
		
				
	}

erst wenn in einem schleifendurchlauf nichts mehr getrennt wurde, wird die liste zurückgegeben.

das ganze dauert mir zu lange - wie kann ich da noch ein paar iterationen rausnehmen?
 
S

SlaterB

Gast
was heißt denn 'dauert dir zu lange'?
hast du 10 Millionen Wörter, für die 3 Sekunden zu viel Zeit ist?
oder eine genauere Zeitangabe

> tlist3 = this.splitOnce(tempword);
deutet an, dass splitOnce selber eine Liste erstellt und zurückgibt,
dann ist zumindest
> List<String> tlist3 = new LinkedList<String>();
sinnlos,
List<String> tlist3 = null;
geht genauso,

generell kann man überlegen, die Listen nicht ständig neu zu erzeugen,
erstelle drei Listen als Klassenattribute und verwende diese wieder, statt neue zu erzeugen
(bringt natürlich nur was, wenn auch das gesamte Splitter-Objekt wiederverwendet wird, statt jedes mal ein neues),
aber das kostet kaum messbare Zeit, genau wie der Rest deines Codes

wenn irgendwas lange dauert, dann vielleicht splitOnce, dazu fehlt der Code
 

Painii

Bekanntes Mitglied
Java:
protected List<String> iterativeSplit(String word){
		
		
		List<String> tlist1 = new LinkedList<String>();
		List<String> tlist2 = new LinkedList<String>();
		List<String> tlist3 = new LinkedList<String>();
		tlist1.add(word);
		boolean splitted;
		while(true){
			splitted = false;
			for(String tempword : tlist1){
				
				tlist3 = this.splitOnce(tempword);
				if(tlist3.size() > 1){
					
					splitted = true;
					
				}
				tlist2.addAll(tlist3); //tlist2 = tlist3
			
			}
			
			if(splitted == false){
				
				return tlist1;
				
			}else{
				
				tlist1.clear();
				tlist1.addAll(tlist2); //tlist1 = tlist 2
				tlist2.clear(); //tlist2 = leer
				
			}
			
		}
		
				
	}
So wie ich das sehe nimmt diene tlist2 die tlist3 auf und evtl. nimmt tlist1 noch tlist2 auf.
Da kannst du das tlist2 gleich so rausschmeissen.

Java:
protected List<String> iterativeSplit(String word){
		List<String> tlist1 = new LinkedList<String>();
		List<String> tlist3 = new LinkedList<String>();
		tlist1.add(word);
		boolean splitted;
		while(true){
			splitted = false;
			for(String tempword : tlist1){
				tlist3 = this.splitOnce(tempword);
				if(tlist3.size() > 1){
					splitted = true;	
				}
			}
			if(splitted == false){
				return tlist1;
			}else{
				tlist1.clear();
				tlist1.addAll(tlist3); //tlist1 = tlist 2		
			}
			
		}			
	}

Da würde einmal die Kopie von tlist2 und einmal das leeren von tlist2 rausfallen performancemässig... wieviel das hilft weiss ich nicht, für den rest müsste man splitonce angucken (um ein "wahrscheinliches" wort zu suchen, wie geht das? in einer db nachschauen ob es so ein wort gibt? nach vokalen suchen? das ist wohl so das wichtigere dran)
 

feuervogel

Mitglied
hi,

vielen dank erstmal für die antworten. zu langsam bedeutet zunächst einmal, dass ich andere komponenten habe in meinem code, die bedeutend schneller sind und das sozusagen der langsamste teil ist. konkret brauchts für ~835.000 bunt durcheinander gewürfelte wörter 413351 ms. EDIT: hm, vielleicht haben meine minimalen veränderungen vom originalcode schon was gebracht...


splitonce besteht nur aus if-abfragen und aus vier aufrufen eines prefixtrees, der nur dafür programmiert wurde, schnell auf die daten zuzugreifen. das kann ich gerne zeigen:

Java:
	protected List<String> splitOnce(String word){
		this.logger.debug("splitting: " + word);
		
		
		List<String> retlist = new LinkedList<String>();
		
		int forw;
		double probforw = -1.;
		int backw;
		double probbackw = -1.;
		try {
			forw = Integer.valueOf(this.forwardsplittingtree.classify(word))
					.intValue();
			
		} catch (NumberFormatException exc) {

			forw = -1;
			probforw = 0.0;

		}

		try {
			backw = Integer.valueOf(this.backwardsplittingtree.classify(word))
					.intValue();

			
		} catch (NumberFormatException exc) {

			backw = -1;
			probbackw = 0.0;

		}

		//if one of the points is out of word boundaries:
		if(backw <= 0 || backw >= word.length()){
			this.logger.debug("backw is out of word boundaries");
			backw = -1;
			probbackw = 0.0;
			
		}
		
		if(forw <= 0 || forw >= word.length()){
			this.logger.debug("forw is out of word boundaries");
			forw = -1;
			probforw = -1;
			
		}
		
		//both are undecided or segmentation points are out of word bounds
		//don't segment
		if((forw <= 0 && backw <= 0) || (forw >= word.length() && backw >= word.length())){
			this.logger.debug("both are undecided or both are out of bounds");
			retlist.add(word);
		
			return retlist;
			
		}
		
		//both predict the same point
		//segment at this point
		if(forw == word.length() - backw){
			this.logger.debug("both predict the same point");
			retlist.add(word.substring(0, forw));
			retlist.add(word.substring(forw));
		
			return retlist;		
						
		}
		
		//forward tree is undecided
		//segment at backwards trees point, if it is not out of word bounds
		if(forw == -1 && backw > -1){
			this.logger.debug("forw tree is undecided");
			retlist.add(word.substring(0, word.length()-backw));
			retlist.add(word.substring(word.length()-backw));
		
			return retlist;
			
		}
		
		//same for backward tree
		if(backw == -1 && forw > -1){
			this.logger.debug("backw is undecided");
			retlist.add(word.substring(0, forw));
			retlist.add(word.substring(forw));
		
			return retlist;
			
		}
		
		if(probforw < 0.){
			
			probforw = this.forwardsplittingtree.getProbabilityForClass(word,
					new Integer(forw).toString());
			
		}
		
		if(probbackw < 0.){
			
			probbackw = this.backwardsplittingtree.getProbabilityForClass(word,
					new Integer(backw).toString());
			
		}		
		
		if(probbackw > probforw){
			this.logger.debug("probback is higher than probforw");
			retlist.add(word.substring(0, word.length()-backw));
			retlist.add(word.substring(word.length()-backw));
		
			return retlist;
			
			
		}
		
		if(probforw > probbackw){
			this.logger.debug("probforw is higher than probbackw");
			retlist.add(word.substring(0, forw));
			retlist.add(word.substring(forw));
		
			return retlist;
			
						
		}
		
		this.logger.debug("noone of the ones above");
		retlist.add(word);
	
		return retlist;
		
		
	}

den algorithmus für split once habe ich aus nem paper quasi abgetippt, da lässt sich nicht viel machen...
 
Zuletzt bearbeitet:
S

SlaterB

Gast
lasse splitOnce() weg und bzw. verkürze auf eine Testklasse, die ein oder mehrere verschiedene vorgefertigte Listen zurückgibt
(mehrere, um while-Schleife beim Aufrufer auch mehrmals laufen zu lassen)

schon werden aus den 400 sec sicher 40 oder 4,

> catch NumberFormatException deutet auf Integer.parseInt hin,
der Code für
forwardsplittingtree.classify(word)
fehlt mal wieder..

new Integer, parsen, und vor allem subString sind vergleichsweise teure Methoden,
bisschen teurer als die neuen LinkedList, aber ob das schon für 400 Sekunden Dauer sorgt?

in der Region ist selbst
> this.logger.debug("splitting: " + word);
ein Faktor, hier wird immer ein neuer String aus zwei alten zusammengebaut, von den internen Logger-Aktionen ganz zu schweigen,
is der logger vielleicht abgeschaltet? zumindest das Zusammenbauen des Parameters muss immer noch jedes Mal geschehen,
wenn du auf die Zeit wertlegst, dann
if (logger.isDebugEnabled() {
..
}
so muss nur ein boolean geprüft werden, was sonst intern auch passiert, aber die Parameter-String-Erzeugung ersparst du dir



und wer weiß was
forwardsplittingtree.getProbabilityForClass
usw. noch alles machen

-----

einigermaßen sparsam wäre aus dem sichtbaren, den String nur maximal einmal in alle benötigten Endstücke zu teilen,
vorher nur die ganzen Indexe sammeln,

Integer.parseInt muss auch weg mit dem try/ catch, alle Zeichen selber als char anschauen, als int interpretieren und zusammenrechnen

aber mich würde es nicht wundern, wenn alles bisher genannte aus denn 400 sec nur 380 sec macht und die Zeit immer noch woanders liegt
 

feuervogel

Mitglied
lasse splitOnce() weg und bzw. verkürze auf eine Testklasse, die ein oder mehrere verschiedene vorgefertigte Listen zurückgibt
(mehrere, um while-Schleife beim Aufrufer auch mehrmals laufen zu lassen)

schon werden aus den 400 sec sicher 40 oder 4,

Alles klar, werde ich ausprobieren.

> catch NumberFormatException deutet auf Integer.parseInt hin,
der Code für
forwardsplittingtree.classify(word)
fehlt mal wieder..

Richtig, der wird auch weiterhin fehlen. Ich will den ja auch nicht performanter machen, zudem ist der Eigentum meiner Uni und ich darf den nicht einfach irgendwo posten.

new Integer, parsen, und vor allem subString sind vergleichsweise teure Methoden,
bisschen teurer als die neuen LinkedList, aber ob das schon für 400 Sekunden Dauer sorgt?

in der Region ist selbst
> this.logger.debug("splitting: " + word);
ein Faktor, hier wird immer ein neuer String aus zwei alten zusammengebaut, von den internen Logger-Aktionen ganz zu schweigen,
is der logger vielleicht abgeschaltet? zumindest das Zusammenbauen des Parameters muss immer noch jedes Mal geschehen,
wenn du auf die Zeit wertlegst, dann
if (logger.isDebugEnabled() {
..
}
so muss nur ein boolean geprüft werden, was sonst intern auch passiert, aber die Parameter-String-Erzeugung ersparst du dir



und wer weiß was
forwardsplittingtree.getProbabilityForClass
usw. noch alles machen

-----

einigermaßen sparsam wäre aus dem sichtbaren, den String nur maximal einmal in alle benötigten Endstücke zu teilen,
vorher nur die ganzen Indexe sammeln,

Integer.parseInt muss auch weg mit dem try/ catch, alle Zeichen selber als char anschauen, als int interpretieren und zusammenrechnen

aber mich würde es nicht wundern, wenn alles bisher genannte aus denn 400 sec nur 380 sec macht und die Zeit immer noch woanders liegt

okay, ich werde mal genauer messen und berichten.
 

kowa

Aktives Mitglied
jvisualvm im JDK/bin Ordner monitort alle Methoden / Threads / etc

Dazu das Plugin visualgc installieren und du kannst die Speicherverwaltung beobachten.

Man kann die Performance auch erhöhen, indem man an den jvm Parametern schraubt. Z.B. gibst du deinem Programm mehr Speicher mit. Wenn man das richtig macht kannst du die Garbage Collector Events so steuern, dass relativ wenig CPU-Last verursacht wird. Hat bei mir mal die CPU-Last halbiert.

Mehr dazu hier.
 

FArt

Top Contributor
Nichtsestotrotz: wer blind am Code oder an Konfigurationen schraubt optimiert nicht sonder rät.

Erst messen, dann bewerten, dann schrauben...
 
J

JohannisderKaeufer

Gast
Erst messen, dann bewerten, dann schrauben...

Erst messen, dann bewerten und bevor geschraubt wird einen Test schreiben sofern noch nicht geschehen...

Es geht ja nicht nur um das schnelle, sondern hoffentlich vor allem um das korrekte Ergebnis.
 

FArt

Top Contributor
Test schreiben noch an ALLERERSTE stelle - dann ist meist messen & bewerten so und so ueberfluessig...
Bitte?
Die Korrektheit des Codes war vorausgesetzt. Es ging um Performancetuning. Was haben Tests damit zu tun?

Ok, ich kann u.U. die Performanceprobleme im Test nachstellen, dazu kann man Lasttests heranziehen. Aber egal wie: messen, bewerten, schrauben... wird auch durch Tests nicht überflüssig.
 

schalentier

Gesperrter Benutzer
Ich denke es ist gemeint, dass wohl niemand ruhigen Gewissens an der Performance schrauben kann, wenn es keinen Test gibt, um die Korrektheit sicherzustellen...
 

FArt

Top Contributor
ich habe nur eine generelle Aussage eines Forenmitglieds verbessert - mehr nicht
cool, ich auch ;-)

Ich denke es ist gemeint, dass wohl niemand ruhigen Gewissens an der Performance schrauben kann, wenn es keinen Test gibt, um die Korrektheit sicherzustellen...
Stimmt aber nicht. Es gibt mehr als genug Fälle, die ich nicht (oder nicht mit vertretbarem Aufwand) über einen Test nachstellen kann. Mir genügen aber Messung z.B. über Monitoring, einen Profiler, ... mit sehr gutem Gewissen sogar ;-)
 
B

bygones

Gast
Stimmt aber nicht. Es gibt mehr als genug Fälle, die ich nicht (oder nicht mit vertretbarem Aufwand) über einen Test nachstellen kann. Mir genügen aber Messung z.B. über Monitoring, einen Profiler, ... mit sehr gutem Gewissen sogar ;-)
ich hoffe du meinst Faelle des Performancetunings... selbst da wuerde ich nicht viel rumdoktern wenn man keine Tests im Hintergrund hat die einem nicht sicherstellen dass die neuen super features nicht die logik zerstoeren

More computing sins are committed in the name of efficiency
(without necessarily achieving it)
than for any other single reason - including blind stupidity.
 

feuervogel

Mitglied
also ich hab es jetzt so gelöst, dass ich eine map fürs caching eingefügt habe, das sich für jedes wort die zerlegung merkt - damit konnte ich schon mal einiges verbessern, u.a. weil vorher jedes wort mind. zwei mal zerlegt wurde. verbraucht zwar mehr speicher, beschleunigt aber um ein vielfaches.

die vorgeschlagenen werkzeuge werde ich bis zum wochenende ausprobieren, vielen dank für die zahlreichen tipps.
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Performanzprobleme mit Java6 Allgemeine Java-Themen 11
M Unsicher, ob das Code richtig ist Allgemeine Java-Themen 4
MarvinsDepression Unbekanntes Zeichen in fremden Code wirft Fragen auf Allgemeine Java-Themen 4
schemil053 Methoden Code-Verbesserung Allgemeine Java-Themen 2
D Webarchive (war): Code verschleiern Allgemeine Java-Themen 7
D Compiler-Fehler child process exited with code 1 Allgemeine Java-Themen 1
Queenman Interface Mein Microsoft Visual Studio Code zeigt komische Dinge & Menüs an Allgemeine Java-Themen 9
A Clean Code: Variable vs. Methode Allgemeine Java-Themen 8
berserkerdq2 Versteht jemand, was diese beiden Zahlen bei dem IJVM Code zu bedeuten haben? Allgemeine Java-Themen 10
OnDemand Releaseversion Tag in Code Allgemeine Java-Themen 5
ERlK JDA Code funktioniert nicht? Allgemeine Java-Themen 4
F Code auslagern Allgemeine Java-Themen 5
D VBA Code mit Java ausführen möglich? Allgemeine Java-Themen 10
N JAVA-Code mit Grafikfenster zeichnet in Windows, aber nicht Mac. Allgemeine Java-Themen 4
JordenJost Unverständlicher Java code? Allgemeine Java-Themen 21
V Hilfe mit Java Code Allgemeine Java-Themen 4
S Processing Java Code verstehen Allgemeine Java-Themen 4
A code wird nicht ausgeführt Allgemeine Java-Themen 3
B Bitte um Code Erklärung Allgemeine Java-Themen 5
N nicht einsehbarer Fehler im code, kann nicht mehr übersetzten Allgemeine Java-Themen 51
N Regulären Ausdruck in normalen Java-Code umwandeln Allgemeine Java-Themen 12
OnDemand Clean Code oder Allgemeine Java-Themen 5
Noahscript Aus einem byte Array Steuerungszeichen und Code bekommen und ersetzen Allgemeine Java-Themen 3
J Simple Date Format Alternativen bitte um Code Allgemeine Java-Themen 14
AGW in Java-Code plötzlich ein paar Wörter in Rot Allgemeine Java-Themen 2
L Best Practice Auslagerung von Code = Performance Optimierung? Allgemeine Java-Themen 4
H Precompilierten code ansehen Allgemeine Java-Themen 3
R Wo müsste ich im Code eine Änderung vornehmen? Allgemeine Java-Themen 6
L Ausgabe von in Echtzeit ausgeführten Code Allgemeine Java-Themen 9
Drachenbauer Wie kann ich die menge an code reduzieren? Allgemeine Java-Themen 28
Thallius Warum ist dieser Code OS abhängig? Allgemeine Java-Themen 10
S Code Erklärung Allgemeine Java-Themen 21
B Pausem im Code Allgemeine Java-Themen 2
T Java-Quiz Code Fehler Allgemeine Java-Themen 10
L Eclipse Java Code ausführen Allgemeine Java-Themen 18
F Java Code ausführen direkt nach Anmelden in Windows Allgemeine Java-Themen 2
F Code in Klassen bringen Allgemeine Java-Themen 4
S Gibt es eigentlich Java Source Code Interpreter..? Allgemeine Java-Themen 13
J JUnit - Auslassen von Code Allgemeine Java-Themen 25
F Klassen Spaghetti Code Vermeidung Allgemeine Java-Themen 16
C code oder Bibliotheken für 2-Center Problem Allgemeine Java-Themen 4
J Code Page characters darstellen Allgemeine Java-Themen 12
J wie sollte man sinnvoll seinen Code aufteilen Allgemeine Java-Themen 6
I Python Code in Java Code Allgemeine Java-Themen 9
M Java (GUI) Code verdoppeln oder anzeige mehrmals anzeigen? Allgemeine Java-Themen 8
N Wie öffne ich einen runtergeladadenen Code in IntelliJ Allgemeine Java-Themen 3
R Fehler im Code Allgemeine Java-Themen 1
R Fehler im Code Allgemeine Java-Themen 3
O Standard library nativer C code Allgemeine Java-Themen 1
R Wo ist mein Fehler in diesem Code Allgemeine Java-Themen 7
S Java Editor Bekomme bei der Code-Vervollständigung die Zeichen &#8203; Allgemeine Java-Themen 3
N Morse Code decoder Allgemeine Java-Themen 9
O Erste Schritte Benzinverbrauch Code Hilfe Allgemeine Java-Themen 3
S Eclipse exit code 805306369 Allgemeine Java-Themen 1
Pataraca Vererbung Code einbinden Allgemeine Java-Themen 3
Developer_X Website HTML Code von HTTPS URL laden Allgemeine Java-Themen 0
S Wie kann ich eine kleine Stelle in meinem Code mit multiplen Threads abarbeiten..? Allgemeine Java-Themen 20
S Code 'innerhalb' des synchronen Bereichs einer BlockingQueue ausfuehren..? Allgemeine Java-Themen 7
F Verständlichkeitsproblem bei Java Code?! Allgemeine Java-Themen 2
G Eclipse Eclipse: Unreachable code Allgemeine Java-Themen 16
P Java Android Code in IOS compilieren? Allgemeine Java-Themen 9
C Code vereinfachen Allgemeine Java-Themen 2
T Hilfe bei Code Allgemeine Java-Themen 3
R Java-Code für folgene Aufgabe? Allgemeine Java-Themen 8
Prafy Best Practice Code Refaktorisierung Allgemeine Java-Themen 7
WetWer Was bedeutet/macht ein Exit-Code Allgemeine Java-Themen 1
D Code für bereitgestellte Methoden Allgemeine Java-Themen 1
perlenfischer1984 HTML Code decodieren Allgemeine Java-Themen 2
C ASCII-Code in Java Allgemeine Java-Themen 1
J Java-Code in DLL packen Allgemeine Java-Themen 5
J LWJGL 3 Error Code 1282 Allgemeine Java-Themen 4
0 Code startet nicht (Keine Warnung/Fehlermeldung) Allgemeine Java-Themen 4
A Frage zu meinem Code Allgemeine Java-Themen 2
B Code generierung Velocity Templates Telosys Allgemeine Java-Themen 1
E Fehlermeldung vor dem Programm code Allgemeine Java-Themen 1
B JAVA - mehrere Clienten gleichzeitig starten. Nicht bei Code! Allgemeine Java-Themen 3
Fischkralle Ausführen von fremden Code Allgemeine Java-Themen 14
wolfgang63 Code snipped Software Allgemeine Java-Themen 1
L Eclipse Editieren des Code templates für Override methods Allgemeine Java-Themen 2
J Java code "plugin" fähig machen Allgemeine Java-Themen 4
alderwaran .jar Code Signing, User-Keystore und Fragen dazu Allgemeine Java-Themen 0
Thallius Wie verstecke ich meinen private Key am besten im Code? Allgemeine Java-Themen 10
A Thread: Code paralell ausführen in mehreren Instanzen Allgemeine Java-Themen 1
B NullPointerException - Aber kein Fehler im Code Allgemeine Java-Themen 4
N HTTP response code: 403 Allgemeine Java-Themen 3
D Code bitte mit 19 stelligen Zahlen kompatibel machen Allgemeine Java-Themen 5
D Java Compiler code referencen Allgemeine Java-Themen 0
B Fehler im Java-Code Allgemeine Java-Themen 4
A PHP-Code zu Java-Code Allgemeine Java-Themen 5
M Code läuft unter windows aber nicht unter Linux Allgemeine Java-Themen 6
X Was macht folgender Code!? Allgemeine Java-Themen 6
K Code zu einem Projekt entschluesseln Allgemeine Java-Themen 15
H Java Leistungssteigerung durch Code Anpassung Allgemeine Java-Themen 5
Fab1 Best Practice Vorgehensweise bestehenden Code/Programm verschönern Allgemeine Java-Themen 4
M Code optimieren Allgemeine Java-Themen 7
A jEditorPane Html Datei öffnen (code) Allgemeine Java-Themen 3
S EAN-Code Tabelle für CD's Allgemeine Java-Themen 2
T Code durch eigenes Frame pausieren (ähnlich JDialog) Allgemeine Java-Themen 4
J Erzeugung von Java-Code Allgemeine Java-Themen 2
A Source code analyze Allgemeine Java-Themen 8

Ähnliche Java Themen

Neue Themen


Oben