Java schneller als C++?!



  • --



  • Artchi schrieb:

    Aber auch C++ schläft nicht und MS will ja mit VC++2005 so ein neues intelligentes Compile- und Link-Verfahren raus bringen, das C++ nochmal deutlich in der Performance pushen soll. Leider habe ich den langen englischen Text zu dem Verfahren nicht ganz verstanden... hat sich aber spektakulär gelesen. 😉

    Du denkst dann, dass dann C++ wieder ein Vorsprung gegenüber Java hat. Falsch gedacht! In welcher Sprache ist wohl Java programmiert?! Genau, in C++. Und wenn C++-Compiler an Geschwindigkeit zulegen, dann tut das Java auch; so einfach ist das.
    Zudem soll Java 1.6 noch mal schneller werden weil die VM multithreaded läuft.



  • Die VM hat immer mehrere Threads. Was neues kommen soll ist was anderes. Normal läuft jedes Java-Programm in einer eigenen Instanz der JVM. Nun soll jedes neue Programm in der selben, einzigen Instanz laufen, also praktisch nicht mehr als ein weiterer Thread in der aktuellen VM sein, anstatt ein eigener Prozess. Das kann natürlich enorm Speicher-Overhead reduzieren und auch JIT-Compilierzeit sparen. Dann darf die JVM aber echt nicht abstürzen, sonst sind _alle_ laufenden Java-Programme futsch.

    Ob das allerdings für 1.6 schon fertig wird, davon weiß ich noch nichts.



  • Allerdings ist deine Schlussfolgerung, dass Java mit C++ automatisch schneller wird, falsch. Die JVM mag schneller werden, aber dass sie aus dem Bytecode dadurch besseren Native Code generiert, ist wohl nicht der Fall. Hier muss man schon den JIT-Compiler verbessern.



  • Optimizer schrieb:

    Die JVM mag schneller werden...

    Genau das meinte ich. Nicht mehr und nicht weniger.

    LG



  • Optimizer schrieb:

    Normal läuft jedes Java-Programm in einer eigenen Instanz der JVM. Nun soll jedes neue Programm in der selben, einzigen Instanz laufen, also praktisch nicht mehr als ein weiterer Thread in der aktuellen VM sein, anstatt ein eigener Prozess. Das kann natürlich enorm Speicher-Overhead reduzieren und auch JIT-Compilierzeit sparen. Dann darf die JVM aber echt nicht abstürzen, sonst sind _alle_ laufenden Java-Programme futsch.

    Das ist schlecht, weil's schwierig wird unter Systemen die kein 'native Threading' kennen. Die Java-Entwickler scheinen das Ganze für Windows optimieren zu wollen, haben aber dabei nicht beachtet, daß die Ressourcen und der Managementaufwand, die/den ein Prozeß belegt verschwindend gering sind gegenüber dem eine Threads.



  • Javaianer schrieb:

    haben aber dabei nicht beachtet, daß die Ressourcen und der Managementaufwand, die/den ein Prozeß belegt verschwindend gering sind gegenüber dem eine Threads.

    Äh, es geht nicht Prozess Versus Thread sondern eine VM pro Anwendung.
    Und das ist sehr wohl eine Katastrophe.

    Momentan geht das noch ganz gut, weil man kaum 2 Java Programme gleichzeitig offen hat. Aber wenn ich auf meinem Notebook Netbeans und JEdit öffne, dann geht nichts mehr, deshalb ist JEdit geflogen und durch einen anderen Editor ersetzt worden.

    Die Optimierung dass nur eine VM für alle Anwendung nötig ist, bringt verdammt viel. Das ganze ist für das Java Programm aber unsichtbar, denn für das Programm ist es ja egal ob es seine eigene VM hat oder sie sich teilt.

    Ich verstehe deinen Einwand daher nicht.



  • Shade Of Mine schrieb:

    Äh, es geht nicht Prozess Versus Thread sondern eine VM pro Anwendung.
    Und das ist sehr wohl eine Katastrophe.

    Eigentlich nicht, da der ausführbare Code der VM nur einmal in den Speicher geladen werden muß. Es liegt daran, daß die VMs von vorn herein einen großen Working Set anlegen, der nicht geshared werden kann. Sicher, eine VM pro System würde dieses Problem verringern, allerdings zu einem Preis, den Optimizer schon genannt hat. Im Endeffekt hätte man dann eine abgewandelte Version des Tomcats.



  • JavaKid schrieb:

    Eigentlich nicht, da der ausführbare Code der VM nur einmal in den Speicher geladen werden muß.

    Ja, aber bedenke: du hast pro Anwendung den gesamten VM Overhead.
    dh, es können keine Resourcen zwischen den Anwendungen geshared werden. Man hat die ganzen Initialisierungskosten der VM jedesmal (schau dir mal an wie schnell eine .NET Anwendung im Gegensatz zu einer Java Anwendung startet).

    Es macht durchaus sehr viel Sinn die VM nur einmal zu starten.
    Natürlich ist es komplizierter, aber IMHO ist es das Wert.

    Mal abgesehen dass es bei Java vermutlich sinnlos sein wird, dass zu tun. Denn fast jede Anwendung bringt ihre eigene JRE mit. An dieser Stelle hat Sun IMHO versagt irgendetwas einheitliches zu machen. Vielleicht wäre es nicht möglich gewesen diese Entwicklung zu stoppen, aber Tatsache ist, dass dies ein gehöriger Nachteil für Java geworden ist.

    Denn meistens hat ein User nun 5mal die JRE drauf und updaten tut er logischerweise keine. Das ist echt ungut 😞

    Somit ist das Feature: nur eine VM pro Anwendung zwar im Prinzip super, nur für Java in der momentanen Situation vernachlässigbar.



  • @Shade: Weil es sich gerade so angehört hat, das i.A. schnellere Starten einer .Net Anwendung liegt nicht daran, dass die Instanz des Frameworks geshared würde (was AFAIK nicht der Fall ist), sondern daran, dass die ganze Klassenbibliothek des Frameworks bei der Installation zu native code vorcompiliert wird. Eine Java-Anwendung dagegen compiliert bei jedem Starten java.lang.String neu. Genau dieser Punkt könnte aber bedeutungsloser werden, denn durch die "shared VM" würde nur noch die erste Java-Anwendung deswegen langsamer starten.

    Wahrscheinlich suckt es aber dann schon wieder, wenn ich Eclipse starte, Eclipse beende (keine andere Anwendung laufen habe) und wieder starte. Da ist der native cache irgendwie ein Vorteil bei der JIT-Compilierzeit.
    Trotzdem sehe ich dieses .Net Feature irgendwie mit gemischten Gefühlen, ich glaube zum Beispiel, dass Inlining der Bibliotheksmethoden in den eigenen Programmcode damit unmöglich geworden ist.

    Kann natürlich auch sein, dass der JIT-Compiler von Microsoft einfach geiler ist. 😃 Irgendwie ham die das Compilerbauen schon drauf. Den VC++ - Compiler find ich um Welten besser als den g++ und der C#-Compiler ist nur noch unfassbar schnell. Da rollen sich einem echt die Zehennägel auf.



  • Übrigens full ack bei dem Desaster mit der JRE. Ich verstehe auch nie so ganz, warum die Leute das machen. Man kann heute noch Java 1.0 Code auf der 1.5 VM ausführen und das war auch klar, dass das immer gehen wird.



  • Shade Of Mine schrieb:

    Denn fast jede Anwendung bringt ihre eigene JRE mit.

    Was dummerweise verhindert, daß das Betriebssystem die JVMs sharen kann, da es verschiedene sind.

    Optimizer schrieb:

    Übrigens full ack bei dem Desaster mit der JRE. Ich verstehe auch nie so ganz, warum die Leute das machen.

    Vielleicht wollen sie absolut sicher gehen, daß ihre Anwendung überall gleich läuft und aussieht



  • Optimizer schrieb:

    Übrigens full ack bei dem Desaster mit der JRE. Ich verstehe auch nie so ganz, warum die Leute das machen. Man kann heute noch Java 1.0 Code auf der 1.5 VM ausführen und das war auch klar, dass das immer gehen wird.

    Ich habe Hoffnung, dass sich das durch den relativ neuen Update-Mechanismus und weiterer Neuerungen bezüglich der Installation und Verbreitung von Javaprogrammen verbessert. Der ist zwar noch nicht wirklich verlässlich, aber bis die MVM kommt, sollte der schon lange Zeit stabil laufen. Die MVM wird wohl frühestens mit Java 7.0 kommen. Bis dahin ist noch Zeit.



  • Optimizer schrieb:

    Weil es sich gerade so angehört hat, das i.A. schnellere Starten einer .Net Anwendung liegt nicht daran, dass die Instanz des Frameworks geshared würde (was AFAIK nicht der Fall ist)

    Echt? Hast du da einen Link dazu? Ich dachte nämlich immer, dass es nur eine VM Instanz gibt...



  • Hmmmm es handelt sich hier AFAIK um diese Application Domains, die man programmatisch nutzen kann um ein Programm im selben Prozess aber dennoch mit einer Prozess<->Prozess - Abgrenzung nutzen zu können. Jetzt les ich aber grad noch irgendwas mit runtime hosts, die AppDomains erstellen und bin verwirrt, weil ich nicht weiß, ob das jetzt automatisch geschieht oder nicht. 😞



  • Hallo ich habe eine Anwendung zum bearbeiten von Datensätzen geschreiben und war ebenfalls verblüfft über die Geschwindigkeit von Java. Zum parsen von 140.000 Datensätzen werden je nach Optionen gerade mal 8-15 sec benötigt, wobei jeder Datensatz ca. die Feldlänge von 20 Zeichen hat. Selber verglichen mit dem selben code in C++ habe ich nicht. Aber ich kenne eine ähnliche Anwendung die das gleich macht und in C++ ist die mehr zeit benötigt als meine. Ich habe auch gelesen daß C++ um das bis 10 fache schneller sein soll als java. Aber die Anwendung muss man mir zeigen, die 140.000 Datensätze in 0,8-2 sec parst.

    Grüße



  • java ist schön einfach und bequem und die implementierungszeit kurz - cpp ist mächtig. ob was wo warum um einen konstanten faktor von 0 bis c schneller ist interessiert echt überhaupt nicht - so lange es nicht um sehr zeitkritische probleme geht.

    irgendwo meinte hier einer, dass es nicht frage der sprache, sondern der datenstruktur und des algos ist, um laufzeiten zu optimieren. dem schließe ich mich an.



  • unido schrieb:

    irgendwo meinte hier einer, dass es nicht frage der sprache, sondern der datenstruktur und des algos ist, um laufzeiten zu optimieren. dem schließe ich mich an.

    Naja, das hört sich zwar immer gut an, ist aber nur die halbe Wahrheit. Es sollte in allen Sprachen zur Selbstverständlichkeit eines Programmierers gehören, den besten Algorithmus und die beste Datenstruktur für eine gegebene Aufgabe zu nehmen, wenn es darauf ankommt. Wenn man das nicht hat, dann ist man als Programmierer daran schuld, dass das Programm nicht schnell genug ist und die Schuld liegt dann nicht bei der Sprache, in der man programmiert hat.

    Allerdings kann die Sprache selbst auch ein Faktor sein, der zu Performanceproblemen führen kann. Wenn eine Sprache bestimmte Dinge nicht unterstützt, dann muss man im einfachsten Fall einen großen Mehraufwand betreiben, um entsprechendes zu programmieren oder es geht vielleicht sogar gar nicht. Wenn man diese Sache nun für die maximale Performance braucht, dann hat man ein größeres Problem, das schnell zu massiven Geschwindigkeitseinbußen führen kann.

    Beispiel: Ich beschäftige mich etwas mit Bildverarbeitung. Da wird für den Wert eines Pixels oft ein "unsigned char" in C++ genommen, also ein 8 Bit Datentyp ohne Vorzeichen. Den gibt es aber in Java nicht. Man muss also drumherumarbeiten und ein short nehmen oder immer kompliziert umrechnen. Aber es ist noch viel schlimmer: Man nutzt nämlich auch andere Datentypen für die Werte von Pixeln. In C++ bietet es sich deshalb an, gewisse Algorithmen usw. als Templates zu schreiben. Java bietet aber keine Generics für primitive Datentypen. Man muss sich also wieder etwas einfallen lassen, nimmt beispielsweise eine Menge Redundanz in kauf oder weicht auf einen sogenannten Bottleneck Datentyp aus, für den dann die Algorithmen implementiert werden. Möglicherweise macht man auch eine Kombination aus beidem. Für so einen Bottleneck Datentypen nimmt man dann oft float oder ähnliches. Man hat also plötzlich Algorithmen für einen 4 Byte Fließkommadatentyp, obwohl das Gleiche für einen 8 Bit Ganzzahltyp auch gereicht hätte. Wenn man solche Probleme betrachtet, ist es kein Wunder, wenn das entsprechende Javaprogramm am Schluss um einen Faktor 10 oder größer langsamer als das C++ Programm ist und zusätzlich deutlich mehr Speicherplatz verbraucht. Und so ein Faktor 10 macht natürlich etwas aus. Den kann man nicht einfach mit einem "ist ja nur ein konstanter Faktor" wegwischen. Man muss da 3 Rechnergenerationen warten, bis das Javaprogramm so schnell läuft, wie das C++ Programm heute schon und das kann in vielen Bereichen natürlich als KO-Kriterium gegen Java gewertet werden.

    Allerdings wird das gerade in der Bildverarbeitung ein spezielles Problem sein, welches sich bei vielen anderen Anwendungen nicht derart äußert. Du solltest diesen Beitrag also nicht nehmen, um Java generell für zu lahm zu erklären. Die Frage ist halt, was man braucht.



  • Ich kann eurer Diskusion zwar nicht ganz im Detail folgen, aber müsste man die Ausgabeanweisungen (printf() und so...) nicht nach dem Timer-Ende laufen lassen?
    Das soll ja schließlich ein Mathematik "Benchmark" (wenn man es so nennen kann) sein.



  • roan312 schrieb:

    Ich kann eurer Diskusion zwar nicht ganz im Detail folgen, aber müsste man die Ausgabeanweisungen (printf() und so...) nicht nach dem Timer-Ende laufen lassen?

    Eigentlich schon, aber andererseits verbraucht das fast keine Zeit und ändert wohl nichts am Ergebnis, wenn der Benchmark selbst einige Sekunden andauert.


Anmelden zum Antworten