Lunar
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
lacarpe hat geschrieben: da bin ich wohl (als Nichtprofi) tatsächlich noch auf dem Stand von gestern. Mir kommen java-Programme aber immer noch langsamer vor.... (ich nutze die JVM von Sun).
Das liegt wohl eher an der Oberfläche. Swing GUIs sind eben nicht die schnellsten... Aber es gibt ja andere GUI Toolkits. Als Empfehlung wäre hier SWT zu nennen. Die Eclipse GUI ist damit geschrieben. Von dieser unrühmlichen Ausnahme abgesehen ist Java eigentlich immer mindestens genauso schnell wie C++. lacarpe hat geschrieben: Aber gut. Bedeutet das, was du schreibst, dass die JVM nun gar nicht mehr interpretiert und den Java-Code in Maschinensprache-Binärcode übersetzt? Das wäre natürlich schick. Obwohl ich es kaum glauben kann, denn dafür das vollständig vorweg compiliert wird, ist der Startvorgang doch ziemlich schnell. Aber vielleicht darf ich ja auch Bauklötze staunen 😉
Nein, die JVM von Sun nutzt einen JIT-Compiler. Gerade diese Tatsache ermöglicht es Java ja, die wirklich gute Performance zu erzielen. Ich glaube zwar, daß Suns JVM seit Java 5 den erzeugten Binär auf der Festplatte zwischenspeichert, um die erneute Compilierung von bereits ausgeführten Programmen zu vermeiden, es mag allerdings sein, daß ich mich in diesem Punkt täusche. lacarpe hat geschrieben: @mythos: Wir haben uns in der Firma (in der Tat vor 4 Jahren) mit der Langsamkeit von Java-Frontends (nichts besonderes) rumgeplagt. An Spiele war gar nicht zu denken. Nun gut, ich lasse mich belehren 😉
Also, mit Java3D sind vernünftige 3D Operation problemlos zu realisieren. Gruß lunar
|
JimPanse
Anmeldungsdatum: 1. April 2005
Beiträge: 623
|
Lunar hat geschrieben: Von dieser unrühmlichen Ausnahme abgesehen ist Java eigentlich immer mindestens genauso schnell wie C++.
Rofl das meinste nicht Ernst, oder?
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
lacarpe hat geschrieben:
Hallo dentaku, da bin ich wohl (als Nichtprofi) tatsächlich noch auf dem Stand von gestern. Mir kommen java-Programme aber immer noch langsamer vor.... (ich nutze die JVM von Sun). Aber gut. Bedeutet das, was du schreibst, dass die JVM nun gar nicht mehr interpretiert und den Java-Code in Maschinensprache-Binärcode übersetzt? Das wäre natürlich schick. Obwohl ich es kaum glauben kann, denn dafür das vollständig vorweg compiliert wird, ist der Startvorgang doch ziemlich schnell. Aber vielleicht darf ich ja auch Bauklötze staunen 😉
Nein, einKompilieren während der Startzeit gab es schon im ersten Jahr seit es Java gibt: das sind die sogenannten Just-in-time compiler (JIT). Die haben aber nur begrenzt etwas gebracht, weil sie zwar auf der einen Seite direkt für die Hardware kompilieren können, aber dafür aber nicht viel Zeit haben, weil sonst der Programmstart zu lange dauert. JIT Compiler sind nur eine halbherzige Sache gewesen: bitte vorweg auf die aktuelle Hardware compilieren, aber nicht so lange damit aufhalten ... dass so praktisch nicht optimiert werden kann ist verständlich. Nein, die HotSpot JVMs verbinden Interpreter und Compiler in einem, d.h. das Programm wird direkt gestartet aber interpretiert (⇒ schneller Programmstart). Während der Laufzeit (also praktisch während der gesamten Programmlaufzeit und nicht nur am Start) überwacht die JVM die code Aufrufe und bildet intern Listen von besonders häufig aufgerufenem code (z.B. häufig aufgerufene Methoden). Diese werden erkannt und zur Laufzeit in hochoptimierten Maschinencode direkt übersetzt. Das hat zur Folge, dass ein Programm zunächst etwas langsamer läuft aber nach einigen Sekunden/Minuten deutlich schneller wird. Bei "einfachen" Client Applikation mit GUI wirkt sich das nicht so spektakulär aus wie bei Serverapplikation. Aber es gibt auch eine "Client HotSpot VM" die auch GUI Applikationen beschleunigt. Darüber hinaus wird auf Linux leider nicht standardmäßig hardware OpenGL benutzt. Man muss dies extra mit der Option -Dsun.java2d.opengl=true einschalten, was natürlich kaum einer weiss: > cd /usr/lib/jvm/java-1.5.0-sun/demo/jfc/SwingSet2/
> java -Dsun.java2d.opengl=true -jar SwingSet2.jar Ein Fractalprogramm würde ich z.B. stets mit der Server HotSpot VM laufen lassen statt mit der (voreingestellten) Client HotSpot VM.
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
Lunar hat geschrieben: dentaku hat geschrieben: Seit aber die JVM nicht mehr interpretiert und auch kein JIT Compiler mehr eingesetzt wird, sondern der HotSpot compiler
Der HotSpot Compiler ist ein Just-In-Time Compiler. Nur einer der besseren Sorte... Gruß lunar
Sorry, das ist schlichtweg falsch. Die HotSpot JVMs haben gar nichts mit JIT compilern zu tun. Ein JIT compiler kompiliert den Java Bytecode nur einmal beim Start einer Java Appliaktion. Dies muss sehr schnell gehen, damit der Start nicht zu lange dauert und deshalb können diese Compiler nur wenig optimieren. HotSpot JVMs sind keine compiler im engeren SInn (= code in Maschinencode übersetzen und ausführen) sondern Virtuelle Maschinen die nur Codefragmente des laufenden codes compilieren und zwar höchstoptimiert auf die Hardware und die Laufzeitumgebung. HotSpot JVMs decompilieren (!) auch code zur Laufzeit. Das hat u.a. damit zu tun, dass sich Schwerpunkte des Ausführungspfades ("hot spots") zur Laufzeit auch verlagern können und z.B. die Speicherauslastung reduziert werden kann indem solche Compilate wieder in Bytecode rückübersetzt und nur Interpretiert werden. Dies ist ein recht komplexes Thema und die Realität sieht noch viel komplizierter aus. Man kann beim Start einer Applikation an sehr vielen Schrauben drehen, um die Gewichtung diverser Bewertungskriterien der HotSpot JVM auf seine Bedürfnisse anzupassen. Aber da muss man sehr tief in die Materie einsteigen. Die Voreinstellungen sind für die meisten Fälle schon sehr gut gewählt. JIT compiler sind zu HotSpot VMs wie ... Trabbi zu Mercedes. Lunar hat geschrieben: Nein, die JVM von Sun nutzt einen JIT-Compiler. Gerade diese Tatsache ermöglicht es Java ja, die wirklich gute Performance zu erzielen. Ich glaube zwar, daß Suns JVM seit Java 5 den erzeugten Binär auf der Festplatte zwischenspeichert, um die erneute Compilierung von bereits ausgeführten Programmen zu vermeiden, es mag allerdings sein, daß ich mich in diesem Punkt täusche.
Nein, schon lange nicht mehr. Der JIT compiler wurde von Sun sogar wieder ausgebaut (ich glaube schon ab 1.4), weil die HotSpot JVMs die JITs völlig überflüssig machte (schnellerer Start und schnellere Ausführung des Programmes). Es wird auch nichts auf der Festplatte zwischengespeichert - das wäre viel zu langsam. Dafür brauchen die Programme aber auch mehr Hauptspeicher (ich rede dabei nicht von Client Programmen wie Utilities, CD-Sammlung, kleinen Malprogrammen, etc. sondern von Serverapplikationen). Sorry, aber all diese Falschaussagen kann ich hier so nicht stehen lassen. Denn sie werfen ein ziemlich falsches Bild auf Java wobei leider noch alte Kritikpunkte der ersten Java-Versionen bis Heute als (falsche) Argumente wiederholt werden, die so schon lange nicht mehr bestehen.
|
Lunar
(Themenstarter)
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
dentaku hat geschrieben: Lunar hat geschrieben: dentaku hat geschrieben: Seit aber die JVM nicht mehr interpretiert und auch kein JIT Compiler mehr eingesetzt wird, sondern der HotSpot compiler
Der HotSpot Compiler ist ein Just-In-Time Compiler. Nur einer der besseren Sorte... Gruß lunar
Sorry, das ist schlichtweg falsch. Die HotSpot JVMs haben gar nichts mit JIT compilern zu tun. Ein JIT compiler kompiliert den Java Bytecode nur einmal beim Start einer Java Appliaktion.
Lies dir doch bitte mal JIT-Compiler durch.
Der JIT-Compiler übersetzt während der Laufzeit bei Bedarf den Bytecode in einen nativen Maschinen-Code (also einen Code, den der Prozessor direkt verarbeiten kann). Hochentwickelte JIT-Compiler können speziell für dynamische Sprachen schnelleren Code als herkömmliche Compiler generieren, da sie Closed-World Annahmen treffen können und Dynamische Optimierungen durchführen.
Ein Jit Compiler kompiliert während der Laufzeit eines Programmes und nicht davor. Das wäre sonst ein einfacher Bytecode Compiler. Lunar hat geschrieben: Nein, die JVM von Sun nutzt einen JIT-Compiler. Gerade diese Tatsache ermöglicht es Java ja, die wirklich gute Performance zu erzielen. Ich glaube zwar, daß Suns JVM seit Java 5 den erzeugten Binär auf der Festplatte zwischenspeichert, um die erneute Compilierung von bereits ausgeführten Programmen zu vermeiden, es mag allerdings sein, daß ich mich in diesem Punkt täusche.
Es wird auch nichts auf der Festplatte zwischengespeichert - das wäre viel zu langsam.[/quote] Zumindest die Client VM speichert erzeugten Maschinencode nach der Laufzeit eines Programmes. Bei der nächsten Ausführung eines Programmes wird ein während eines vorherigen Programmlaufes bereits compiliertes Class File von der Festplatte geladen. dentaku hat geschrieben: Dafür brauchen die Programme aber auch mehr Hauptspeicher (ich rede dabei nicht von Client Programmen wie Utilities, CD-Sammlung, kleinen Malprogrammen, etc. sondern von Serverapplikationen).
Das brauchen Java Programme sowieso. Gruß lunar
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
lacarpe hat geschrieben: Entschuldigung, wenn ich noch einmal OT gehe, aber das interessiert mich jetzt: dentaku hat geschrieben: Ein Fractalprogramm würde ich z.B. stets mit der Server HotSpot VM laufen lassen statt mit der (voreingestellten) Client HotSpot VM.
Ich habe ein Java-Programm mit GUI-Oberfläche programmiert. Es gibt hier eine Funktion, die per Button aufgerufen wird und dann 5 Minuten lang nur rechnet, also Daten aus Dateien ausliest und dann verschiedene Operationen vornimmt, ohne dass die GUI wesentlich dabei angesprochen wird. Würde so ein "reiner" Rechenprozess um einiges schneller werden, wenn ich die Server HotSpot VM laufen lasse? Um welchen Faktor schätzungsweise? Und unterstützt diese Server HotSpot VM trotzdem das GUI? Für eine kurze Erklärung wäre ich dankbar. lacarpe
Es ist grundsätzlich egal ob Du ein Programm mit der Client oder Server JVM startest - es läuft mit beiden. Nur optimiert die Client JVM eben clientspezifische Funktionen (wie GUI) und die Server JVM optimiert serverspezifische Funktionen. Insofern kann der Performancegewinn durch die Verwendung der Server JVM deutlich höher sein als der Performanceverlust der nicht genutzten GUI Beschleunigung. Um welchen Faktor ein Programm schneller wird, kann man natürlich nicht allgemein sagen - das kommt ganz auf die Berechnungen an. Du kannst den Performanceunterschied ja einfach testen indem Du das Programm einmal mit "-client" und einmal mit "-server" aufrufst ("java -server -cp ..."). Bitte beachten: wenn das Programm gestartet ist, die zu testenden Funktionen mehrmals aufrufen, damit der HotSpot compiler warm wird! Die erste Ausführung wird stets am längsten dauern. Übrigens: ein grosser Teil von (Geschwindigkeits-)Optimierungen liegt im Code selbst - oft lassen sich sogar erhebliche Geschwindigkeitssteigerungen erzielen, wenn man die Logik und Algorithmen entsprechend durchschaut und optimiert. Insbesondere der häufige Zugriff auf externe Resourcen (Datei, DB, Netz) ist oft Ursache für eine gebremste Ausführung. Schon mit kleinen Caches kann man da Wunder bewirken. 😉
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17599
Wohnort: Berlin
|
lacarpe hat geschrieben: Ich habe ein Java-Programm mit GUI-Oberfläche programmiert. Es gibt hier eine Funktion, die per Button aufgerufen wird und dann 5 Minuten lang nur rechnet, also Daten aus Dateien ausliest und dann verschiedene Operationen vornimmt, ohne dass die GUI wesentlich dabei angesprochen wird. Würde so ein "reiner" Rechenprozess um einiges schneller werden, wenn ich die Server HotSpot VM laufen lasse? Um welchen Faktor schätzungsweise? Und unterstützt diese Server HotSpot VM trotzdem das GUI?
Ja - die Server-VM unterstützt auch das GUI. Wieviel schneller das wird kann Dir aber niemand sagen - auch nicht derjenige, der die Server-VM geschrieben hat (oder diejenigen). Einmal hängt es von Deinem konkreten Programm ab. Dann mit großer Wahrscheinlichkeit von den Daten, die Du liest. Rufe einfach time java MeineKlasse und time java -server MeineKlasse auf, und vergleiche die Zeiten. Am besten wiederholst Du das mehrfach, um zu sehen, ob die Werte über mehrere Aufrufe stabil bleiben. Wenn die JVM aus dem Betriebssystem-Cache geladen werden kann sind die Ergebnisse wahrscheinlich schon anders. Wenn Du java.io statt java.nio benutzt dann kannst Du vielleicht durch einen Wechsel nochmal was rausholen. Gepufferte Streams verwendest Du bestimmt schon. Prinzipiell ist es aber ratsam vor dem Performance-Tuning zu messen, wo das Programm die meiste Zeit verbringt. Ein Codefragment das nur noch halb so lange braucht, aber am Gesamtprogramm nur 0,1% Anteil hat wird sich nicht als Verbesserung bemerkbar machen, wie eines, das nur um 20% verbessert wurde, aber 50% der Laufzeit verschluckt. U.U. kann es auch mehr bringen die Festplatte zu tunen, oder eine schnellere zu kaufen. Die externen Faktoren werden gelegentlich beim Optimieren übersehen.
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
user unknown hat geschrieben: Rufe einfach time java MeineKlasse und time java -server MeineKlasse auf, und vergleiche die Zeiten. Am besten wiederholst Du das mehrfach, um zu sehen, ob die Werte über mehrere Aufrufe stabil bleiben. Wenn die JVM aus dem Betriebssystem-Cache geladen werden kann sind die Ergebnisse wahrscheinlich schon anders.
... was aber nicht viel bringt um die HotSpot JVM zu testen. (Übrigens ist es empfehlenswert bei solchen Tests auch explizit "-client" anzugeben, da auf 64 Bit Rechner per default die Server VM verwendet wird.) Wenn Du mehrere male das ganze Programm startest (time java ...) wird sich der HotSpot compiler gar nicht auswirken. Du musst im Programm eine bestimmte Berechnung mehrere male ausführen. Z.B. auf Deiner GUI mehrere mal den butten "berechnen" nacheinander drücken. Und die Zeit z.B. so messen: final long t = System.currentMillis();
//hier die umfangreichen Berechnungen ...
System.out.println("Duration [ms]: "+(System.currentMillis() - t));
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17599
Wohnort: Berlin
|
Ups! Das es schon eine Seite 3 gibt habe ich beim Antworten übersehen. Daher wiederhole ich teils Sachen, die dentaku bereits geschrieben hat. Ich weiche aber in einem wichtigen Punkt ab: Wenn das Programm eigentlich schon fertig ist, und Du kannst es so testen, wie es auch genutzt wird, dann ist das allemal besser, als isolierte Funktionen zu messen. Und wenn im richtigen Anwendungsfall die Funktion nur einmal aufgerufen wird, dann nützt es nichts zu messen, was passiert, wenn sie das dritte Mal aufgerufen wird. So habe ich lacarpe zumindest verstanden.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17599
Wohnort: Berlin
|
Lunar hat geschrieben: Zumindest die Client VM speichert erzeugten Maschinencode nach der Laufzeit eines Programmes. Bei der nächsten Ausführung eines Programmes wird ein während eines vorherigen Programmlaufes bereits compiliertes Class File von der Festplatte geladen.
Nein. So oder oder - Client oder Server - wird der Bytecode vom Compiler (javac) erzeugt. Und diesen Bytecode bekommen sowohl Client-, als auch Server-VM vorgelegt. Die Client-VM speichert später nichts auf der Festplatte - das wäre mir begegnet. Allenfalls das Betriebssystem kann in seinem Cache Dinge weiter vorhalten - das ist aber nichts, worauf die JVM Einfluß hätte.
|
user_unknown
Anmeldungsdatum: 10. August 2005
Beiträge: 17599
Wohnort: Berlin
|
dentaku hat geschrieben: ... was aber nicht viel bringt um die HotSpot JVM zu testen. Wenn Du mehrere male das ganze Programm startest (time java ...) wird sich der HotSpot compiler gar nicht auswirken. Du musst im Programm eine bestimmte Berechnung mehrere male ausführen. Z.B. auf Deiner GUI mehrere mal den butten "berechnen" nacheinander drücken.
Ich schlage nicht vor, mehrere Messungen durchzuführen, um HotSpot-Effekte zu erzielen, sondern um zu prüfen, ob die Werte stabil bleiben, und Caching-Phänomene des Betriebssystems ins Auge zu bekommen. Der Hotspot-Compiler soll dadurch zuschlagen, daß das Programm 5 Minuten arbeitet, und dabei sicherlich einige Funktionen wiederholt aufruft.
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
@lacarpe: was berechnet Dein Programm denn überhaupt?
|
dentaku
Anmeldungsdatum: 31. Januar 2005
Beiträge: 3778
|
Lunar hat geschrieben: Lies dir doch bitte mal JIT-Compiler durch.
Der JIT-Compiler übersetzt während der Laufzeit bei Bedarf den Bytecode in einen nativen Maschinen-Code (also einen Code, den der Prozessor direkt verarbeiten kann). Hochentwickelte JIT-Compiler können speziell für dynamische Sprachen schnelleren Code als herkömmliche Compiler generieren, da sie Closed-World Annahmen treffen können und Dynamische Optimierungen durchführen.
Ein Jit Compiler kompiliert während der Laufzeit eines Programmes und nicht davor. Das wäre sonst ein einfacher Bytecode Compiler.
Jo, dieser Artikel ist demnach falsch! Ein JIT compiler (zumindest bei Java) kompiliert den code beim Start des Programmes - also weder davor noch während des Programmablaufs. Ein JIT compiler kompiliert am Start auch nur einmal und hat keine Informationen über den aktuellen/häufig genutzten Codepfad. Genau dies ist aber Voraussetzung für die HotSpot JVM. Ein JIT compiler ist nur ein statischer compiler der zwar den Vorteil hat, theoretisch besseren Maschinencode zu generieren als ein herkömmlicher statischer compiler wie z.B. C, weil er auf der Zielhardware übersetzt, aber gleichzeitig eben nur statisch kompilieren kann und nur Spekulationen des Codepfades ableiten und somit nicht optimal übersetzen kann. Die HotSpot JVM ist ein dynamischer compiler und schaut in erster Linie nicht den code an, wie man den schneller macht, sondern er schaut sich die tatsächliche Nutzung des Programmes an und kann so viel besser beurteilen, welche Teile am besten Optimiert werden können (realer Codepfad). Links: HotSpot: A new breed of virtual machine Java SE HotSpot at a Glance Chapter 8 Continued: Performance Features and Tools : Adaptive optimization The Java Hotspot does not include a plug-in JIT compiler but instead compiles and inline methods that appear it has determined as being the most used in the application. This means that on the first pass through the Java bytecodes are interpreted as if you did not have a JIT compiler present. If the code then appears as being a hotspot in your application the hotspot compiler will compiler the bytecodes into native code which is then stored in a cache and inline methods at the same time. See the inlining section for details on the advantages to inlining code. One advantage to selective compilation over a JIT compiler is that the byte compiler can be spend more time generating highly optimized for the areas that would benefit from the optimization most. The compiler can also avoid compiling code that may be best run in interpreted mode. Earlier versions of the Java HotSpot VM were not able to optimize code that was not currently in use. The downside to this is if the application was in a huge busy loop the optimizer would not be able to compile the code for area until the loop had finished. Later Java Hotspot VM releases use on-stack replacement, meaning that code can be compiled into native code even if it is in use by the interpreter.
|
Lunar
(Themenstarter)
Anmeldungsdatum: 17. März 2006
Beiträge: 5792
|
user unknown hat geschrieben: Lunar hat geschrieben: Zumindest die Client VM speichert erzeugten Maschinencode nach der Laufzeit eines Programmes. Bei der nächsten Ausführung eines Programmes wird ein während eines vorherigen Programmlaufes bereits compiliertes Class File von der Festplatte geladen.
Nein.
Jupp, ich hab mich wohl geirrt. 😳 Da war so eine dunkle Erinnerung an eine Funktion zur Optimierung des Startprozesses der JVM. Ich dachte halt, daß geschieht über Zwischenspeichern der compilierten Class files. Was ich wohl tatsächlich gemeint habe, ist Class Data Sharing. Gruß lunar
|
Hello_World
Anmeldungsdatum: 13. Juni 2006
Beiträge: 3620
|
dentaku hat geschrieben: Jo, dieser Artikel ist demnach falsch! Ein JIT compiler (zumindest bei Java) kompiliert den code beim Start des Programmes - also weder davor noch während des Programmablaufs.
Das ist schonmal falsch. Das JIT in JIT-Compiler steht für "Just in Time". Der Code wird also genau dann kompiliert, wenn er zum ersten Mal gebraucht wird und _nicht_ notwendigerweise beim Start des Programms. Sonst würden Programme wie z. B. Eclipse ja ewig zum starten brauchen.
|