• Willkommen im Geoclub - dem größten deutschsprachigen Geocaching-Forum. Registriere dich kostenlos, um alle Inhalte zu sehen und neue Beiträge zu erstellen.

[DEV] Geschwindigkeit

blackeye501

Geocacher
Nachdem immer wieder die Diskussion um dei Geschwindigkeit des gpx-export aufkommt, hab eich mal wieder einen Blick in den Source-Code geworfen. Dabei sind mir ein paar Punkt aufgefallen, die evtl. die Sache beschleunigen könnten.

Für den gpx-Export wird ja (im Gegensatz zu den anderen Exportern) die Langtextbeschreibung benötigt. Diese wir vom CacheHolderDetail ermittelt.

Und da hätte ich die eine oder andere Idee was zu ändern.

- Der CacheHolderDetail lädt immer alle Informationen in die entsprechenden Variablen, obwohl wie beim gpx-Export nur Langtext und Hint benötigt werden.
Wäre es nicht sinnvoll dem CacheHolderDetail mitzugeben welche Informationen benötigt werden ?

- Es wird bei CacheHolderDetail immer zuerst die gesamte xml-Datei in eine Variable geladen, und diese Variable dann für jedes CacheDetail einmal dem Extractor übergeben, der immer vom Anfang bis zum entsprechendem TAG die Varable durchsucht und das Ergebniss anschliesend in die gewünscht Variable schreibt. Ich denke, das dabei mehr Speicher als nötig verwendet wird.
Könnte man nicht die Datei Zeichen für Zeichen lesen und dann wenn das gewünschte Tag auftaucht die entsprechende Variable damit befüllen.

- Kombiniert man jetzt beide Schritte kann evtl. schon nach einlesen der ersten paar Zeilen (wenn die gewünschten TAGs sachon dabei waren) die Datei wieder geschlossen werden.

Ich könnte mir vorstellen, dass bei Umsetzung der Punkt wesentlich weniger Speicher benötigt wird und die Lesezeiten vom Datenträger sinken (da nicht immer die gesamte Datei benötigt wird)

Die Speichernutzung und Freigabe scheint in Java ja ein entscheidender Punkt bei der Geschwindigkeit zu sein. Die garbage collection verbraucht ja schon eine nicht unerhebliche Zeit. Evtl. liegt darin auch der Geschwindigkeitsunterschied zwischen SunJAVA und Ewe. SunJAVA belegt bei der Ausführung vom Cachewolf schon mal schnell 100MB Speicher und mehr. Ewe begnügt sich statt dessen mit 10-15 MB.
 

pfeffer

Geowizard
ich vermute, dass das keine gute Idee ist.
Denn das suchen (nach bestimmten Tags) wird native ausgeführt -> schnell.
Einzelne Zeichen zu lesen müsste in java gemacht werden -> langsam.

Gruß,
Pfeffer.
 
OP
B

blackeye501

Geocacher
Wobei beim export von 930 Caches mit JAVA in 36sek auf P4 2.0 GHz der Zeitanteil der garbage collection schon erheblich ist.
Hab das gerade nochmal getestet. Während des Exports wird pro Cache 9-10x die Garbage collection aufgerufen und daauert jedes mal ca 1/1000s.
Das bedeutet fast 9 sek. wird nur unnützer Speicher wieder freigegeben. Und meine starke Vermutung ist, dass das auf den häufigen Aufruf des Extractors bei gleichzeitiger Übergabe des gesammten Inhalts der xml-Datei zurückzuführen ist.
 

pfeffer

Geowizard
interessant!

Wie siehst Du, wie oft die Garbage Collection aufgerufen wird und wie lange sie dauert?

Hast Du einen Profiler?

Ist ja seltsam, dass die so oft ausgeführt wird. Ich hätte gedacht, die wird nur dann ausgeführt, wenn
a) grad nichts anderes zu tun ist oder
b) der Speicher knapp wird.

Gruß,
Pfeffer.
 
OP
B

blackeye501

Geocacher
Ich rufe die jar Datei folgendermaßen auf:

Code:
java -XX:+PrintGCDetails -cp CacheWolf.jar ewe.applet.Applet CacheWolf.CacheWolf

Ich denke der Tenured Space wird von der Garbage Collection bearbeitet wenn der Speicher knapp wird.
Jedoch die Garbage Collection für den Eden Space wird beim beenden jedes Threads ausgeführt. Wobei jede class wenn sie gestartet wird einen eigen Thread auf macht. (Ich hoffe das stimmt so, bin auch nicht der Java Freak.)

Was auch noch intressant ist es fallen bei jeder Garbage Collection 960 kB an. Das sind dann also bei 930 Caches 8,3 GB Daten die in den Speicher geschrieben und wieder freigegeben werden. Für nen PC eine Kleinigkeit aber auf dem PocketPC.....
 

TweetyHH

Geomaster
Mir ist gerade noch ein nicht unerheblicher Faktor zur Geschwindigkeit eingefallen! Dateizugriffe kosten einfach echt Zeit! Und da die ausführlichen Cachbeschreibungen ja alle eine eigene Datei sind ... Das erklärt vielleicht auch die erheblichen GarbageCollection Zeiten. Er langweilt sich wirklich° Auf den Desktops mag das noch gehen, aber auf kleinen Geräten hab ich die Erfahrung gemacht ist es echt erheblich.

Evtl. könnte man das Exportieren also Beschleunigen wenn man Multithreaded mit 10 Threads meinetwegen 20 Dateien "vorlädt". Andererseits finde ich die Exportzeit auf großen Rechnern mit der Javaversion durchaus akzeptable. Und ich denke mal auf PDAs werdens eher die wenigstens machen, oder? Und wenn sie es doch machen können sie zumindest den PDA 5 Minuten in die Innentasche stecken, dann wird ihnen von der Abwärme wenigstens warm ;-)
 

TweetyHH

Geomaster
Achja: noch ein paar Tipps:
Wer eine Java 6 Umgebung hat kann mit jconsole einen beliebigen Javaprozess Monitoren (Also auch den Cachewolf) - zumindest speicher und prozessorbedarf lässt sich so schön angucken. Einfach erst Cachewolf und dann die jconsole starten.

Was mir noch zum Problem Startzeit bei den "kleinen" eingefallen ist: Das XML Format ist nicht wirklich "optimal" wenn man das letzte bissle Performance ausquetschen möchte. Ich denke eine CommaSeparatedValue Datei wäre da besser, weil man da immer nur einen Index suchen muss und der Zweiten sich durch addieren von 1 finden lässt. Mann muss als Trennzeichen ja kein Komma nehmen sondern irgendwas ganz exotisches. Ob und wieviel das was bringt ... aber vielleicht ein paar % weniger.
 

pfeffer

Geowizard
habe mal ein bißchen mit dem GPX-Exporter mit dem Zweck der Geschwindigkeitssteigerung rumgespielt.

a) Erhöhung des zur Verfügung stehenden Speichers mit -Xmx 120M bwerikt keine Beschleunigung

b) das Geschwindgikeitsproblem resultiert nicht aus dem Einlesen der CacheDetails, sondern die Methode SafeXML.cleanGPX ist das Problem. Wenn man sie durch ein einfaches return str ersetzt, dann reduziert sich die Zeit, die die GPX-Export-Funktion braucht von 11 Minuten auf 37 Sekunden!

Das Einlesen der CacheDetails braucht lediglich 31 Sekunden. (was man dadurch merken kann, dass ein zweiter Aufruf der Exportfunktion nur noch 8 Sekunden braucht, wenn man SafeXML.cleanGPX nicht durchführt.)

Alle Messungen auf dem PC mit Windows-exe.

Also, vielleicht hat irgendein Entwickler eine Idee, wie man diese Funktion effizienter machen könnte.

Gruß,
Pfeffer.
 

TweetyHH

Geomaster
Das Einlesen der CacheDetails braucht lediglich 31 Sekunden. (was man dadurch merken kann, dass ein zweiter Aufruf der Exportfunktion nur noch 8 Sekunden braucht, wenn man SafeXML.cleanGPX nicht durchführt.)

Also, vielleicht hat irgendein Entwickler eine Idee, wie man diese Funktion effizienter machen könnte.
Die Methode STRreplace.replace(String a, String b, String c) war ziemlich Speicherverschwenderisch Programmiert. Es wurden jede Menge Strings erzeugt. Daher hab ich sie mal auf einen StringBuffer geändert. Also fröhliches Testen. Hier sieht alles gut aus.
 
OP
B

blackeye501

Geocacher
Testbedingung: 2,0 GHz P4, WinXP, 930 Caches

Ergebniss mit der BE1130 war:
ewe: 12 min
exe: 12 min
java: 36 sek

Jetzt mit der BE1153:
ewe: 2,5 min
exe: 2,5 min
java: 13 sek

Also was soll man sagen: Voller Erfolg :D
 

TweetyHH

Geomaster
Da die EWE/EXE Version auf gut 1/5 der ursprünglichen Zeit runter ist und die Javaversion "nur" auf eine gutes Drittel reduziert werden konnte, geh ich mal davon aus, dass wahrscheinlich da irgendwo das untere Ende der Fahnenstange erreicht ist, weil die File-IO sich ja nicht beliebig beschleunigen lässt. Es müssen ja 930 Caches = 930 Dateien geöffnet und gelesen werden. Ich schätze (ein wenig Kopfrechnen), dass die reine File IO in der Javaversion ca. 7 bis 8 Sekunden verbrauchen würde. Das macht also 5 bis 6 Sekunden nachdenken, was ein recht ordentlicher Wert ist denke ich mal. Also viel lässt sich da wahrscheinlich nicht mehr machen.
 

pfeffer

Geowizard
ich vermute, dass man es nochmal deutlich beschleunigen kann, wenn man nicht Strings zwischen den Routinen übergibt, sondern den Stream, auf den geschrieben wird. Dann braucht man nämlich überhaupt keine überflüssigen Speicherbelegungen mehr.

Gruß,
Pfeffer.
 

TweetyHH

Geomaster
Ich vermute, dass es nicht so viel sein wird. Kommt dann auch noch darauf an, wie gut die Buffered* in EWE implementiert sind. Wenn man hier was ändern würde hätte ich außerdem Bedenken, dass dann evtl. die gleiche Funktionalität 2 mal geschrieben werden müsste, je nachdem ob irgendwo ein String oder ein Writer/Reader rein oder raus muss.
 
Oben