JAVA schneller als C++ ? Stimmt das???
-
vielleicht macht mal einer den test mit java? das müsste ja eigentlich ähnlich schnelle heapalgorithmen haben, weil man da auch immer mit vielen objekten hantieren muss....
-
cppgast schrieb:
In der c't war schon vor 3 oder 4 Jahren zu lesen, dass C++ von Java im Bereich der Konsolenprogramme locker an die Wand gedrückt wird.
Solchen Sachen solltest du nicht allzu viel Glauben schenken. "Java schneller als C++?" Darauf gibt es keine Antwort. C++ ist eine reine Sprachdefinition, und davon kannst du keine Geschwindigkeit messen. Genauso wenig wie vom BGB. Was du messen kannst, sind Implementationen. Diese zu beurteilen, kann man aber nur subjektiv und nicht objektiv. Ich kann dir 100 Implementierungen zu einem Problem in C++ liefern (glücklicherweise muss ich das nicht
), und jede hat ein anderes Laufzeitverhalten.
Wenn man überhaupt eine objektive Antwort auf die Frage geben kann, dann kannst du das auch ohne irgendwelche Benchmarks, nur rein von der technischen Seite betrachtet. C++ Programme werden idR direkt für die jeweilige Plattform kompiliert, laufen also nativ. Java wird hingegen interpretiert, auch wenn das heutzutage bei weitem nicht mehr so spartanisch abläuft wie zu Basic Zeiten. AFAIK ist es zwar auch möglich, nativen Code zu erzeugen. Das dürfte aber nicht die Regel sein. Wie auch immer, der von der VM verarbeitete übliche Bytecode ist gegenüber nativem Code ein weiterer Zwischenschritt der einfach Laufzeit kostet, weil keine VM der Welt Instruktionen so effizient verarbeiten kann wie ein Prozessor. Die VM kann ja maximal auch nur das machen, was der Prozessor hergibt. Von daher sind C++ Anwendungen auf dem Papier erstmal performanter einzustufen als Java Anwendungen. Wie aber letztendlich die Realität, und damit die konkrete Implementierung aussieht, ist eine ganz andere Geschichte.
Das eigentlich Traurige daran ist, dass man im Netz immer wieder "Dünnbrettbohrer" findet, die von der Materie nicht wirklich Ahnung haben und dann mit Benchmarks _ihre_ Sprache anpreisen.
Auf einer Webseite (Adresse weiss ich leider nicht mehr) habe ich mir mal so einen Benchmark Test zwischen C++ und Java Programmen näher angeschaut. Das war der helle Wahnsinn, was für einen Blödsinn dieser Typ dort gemacht hat. Ich sollte vllt. noch dazu sagen, dass es ein Java Verfechter war und die Ergebnisse auch entsprechend aussahen. Aber das nur nebenbei. Jedenfalls hat er diverse Algorithmen implementiert und die Anwendungen dann mittels eines Skripts mehrfach hintereinander aufgerufen und die Zeit gemessen. Was der Typ aber nicht bedacht hatte, ist, dass die Anwendungen auch beim Start und Beenden Laufzeit verbraten. Die eigenliche Laufzeit des Algorithmus ist somit nur zu einem gewissen Teil im Ergebnis enthalten. Und dieses ist somit vollkommen unbrauchbar. Soviel zum Thema stupide Ignoranten.
-
"JAVA schneller wie C++ ? Stimmt das??? "
Schwachsinn Wer so etwas diskutiert, hat noch nie programmiert.
-
Dauercoder schrieb:
Hi,
also ich hab mal den C++ Code in Managed C++ (CLI) umgeschrieben, sodass man beide Programme am Framework vergleichen kann:
C++: 2093 ms
C#: 2171 ms[snip]
Könnte daran liegen, dass der C++ Compiler/Linker besser Optimiert ist (da es den ja länger gibt
)
Hi,
jepp, daran wirds liegen...
Du gewinnst durch den Benchmark allerdings nichts, da der Algorithmus des .net Frameworks ja der gleiche ist, egal, ob du C# oder C++/CLI verwendest. Aussagen wie "der Allokationsalgorithmus in C++ ist schneller als der in C#" kann man damit also nicht beweisen. (Mal abgesehen davon, dass das ohnehin Schwachsinn ist, da man immer nur den Algorithmus einer C++-Implementation testen kann.)Mich würde mal interessieren, was hier ein angepasster Allokator bringen würde
-
Mit der Sprache hat das nichts zu tun. Eher wird der Allokator der Sprache angepasst, denn man braucht einen den Umständen entsprechend passenden Allokator. In C ist malloc meistens auf das allokieren von wenigen großen Blöcken unterschiedlicher Länge optimiert. In C++ macht man viel mehr mit new rum, deshalb ist die Speicherverwaltung dort auch auf das allokieren vieler kleinerer Blöcke besser optimiert. Am meisten allokiert man in Sprachen wie Java und C#, meistens leben die Objekte auch nur sehr kurz und das ist genau das, was der GC sehr gut behandeln kann.
Möglicherweise wäre das auch für ein typisches C++ Programm die optimalere Lösung als die derzeitigen Implementierungen, aber es ist nicht trivial, einen guten GC zu schreiben und trotzdem Pointer wie in C++ zu erlauben. In C++/CLI geht es auch nur mit dem ^-Zeiger so gut. Das Allokieren mit dem normalen new ist auch dort eher schlechter als gcnew, weil die meisten Programme, wie man sie heute schreibt, einen GC begünstigen.
-
groovemaster schrieb:
Wenn man überhaupt eine objektive Antwort auf die Frage geben kann, dann kannst du das auch ohne irgendwelche Benchmarks, nur rein von der technischen Seite betrachtet. C++ Programme werden idR direkt für die jeweilige Plattform kompiliert, laufen also nativ. Java wird hingegen interpretiert, auch wenn das heutzutage bei weitem nicht mehr so spartanisch abläuft wie zu Basic Zeiten. AFAIK ist es zwar auch möglich, nativen Code zu erzeugen. Das dürfte aber nicht die Regel sein. Wie auch immer, der von der VM verarbeitete übliche Bytecode ist gegenüber nativem Code ein weiterer Zwischenschritt der einfach Laufzeit kostet, weil keine VM der Welt Instruktionen so effizient verarbeiten kann wie ein Prozessor. Die VM kann ja maximal auch nur das machen, was der Prozessor hergibt. Von daher sind C++ Anwendungen auf dem Papier erstmal performanter einzustufen als Java Anwendungen.
Blah blah blah! Hattest Du in deinem Beitrag nicht auch was von "Ahnung haben" und so geschrieben?
Was Du da sagst ist zum eine Verzerrung der Tatsachen und zum anderen heutzutage kein wirklicher Performanceaspekt mehr, wenn es darum geht, ob Java nun schnell oder lahm ist.
1. Es ist deshalb eine Verzerrung der Tatsachen, weil die JVM den Bytecode zur Laufzeit kompiliert. Das geht auch relativ schnell, weil der Bytecode schon relativ nah an einem passenden Maschinencode dran ist. Es macht deshalb nichts aus, weil die dafür benötigte Zeitdauer mehr als so eine Art konstanter Overhead gesehen werden kann. Diese Zeitdauer hängt nicht davon ab, wie komplex die Daten sind, die Du in einen Algorithmus reinschaufelst. Und da Du Performance meistens da brauchst, wo Du viel verarbeiten musst, kann dieser Aspekt eigentlich vernachlässigt werden. Zudem können - wenn Du so prinzipielle Erwägungen machst - bei einer Kompilation zur Laufzeit bessere Optimierungen vorgenommen werden. Hier ist zum einen die genaue darunterliegende Plattform bekannt, zum anderen ist aber auch der Zustand des Programms bekannt. Beide Aspekte könnten - vom Prinzip her - zu besser optimiertem Maschinencode führen. Aber wie Du schon sagst: Die Realität entspricht nicht unbedingt den prinzipiellen Möglichkeiten.
2. Für die Performance von Javaprogrammen sind bestimmte Eigenarten im Sprachdesign von Java deutlich problematischer als der von Dir erwähnte Punkt. Bestimmte Eigenschaften von Java machen einen gut optimierten Code umständlicher zu programmieren, als das vielleicht in C++ der Fall wäre. Ein Beispiel hierfür sind die primitiven Datentypen: Hierfür sind in der Standardbibliothek zum Beispiel keine Containerklassen vorhanden. Java bietet Generizität nur für Objekte. Wenn man also mit den primitiven Datentypen performanten Code bekommen will, muss man sich für diese Extraimplementationen von den benutzten Datenstrukturen und Algorithmen besorgen. Zum Beispiel, indem man eine externe Bibliothek verwendet oder indem man entsprechend redundant jeden Algorithmus mehrmals schreibt. Das ist Umständlich und deshalb überlegt man sich natürlich genau, ob man das an einer gegebenen Stelle wirklich braucht. Und genauso gibt es noch einige weitere Eigenschaften von Java, die performanten Code einfach "umständlich zu programmieren" machen. Die meisten Performanceprobleme, die man mit Javaprogrammen hat, sind eher auf solche Schwierigkeiten zurückzuführen, als auf die typischerweise erwähnten Dinge wie "Interpretierter Code", "GC", "Indexüberprüfungen" usw..
3. Natürlich werden C++ Programme bei den heute üblichen Compilern im Großen und Ganzen etwas schneller laufen als entsprechende Javaprogramme. Java muss nicht die schnellsten Programme liefern. Ich denke, Java hat, trotz seinem Langsam-Image, eine ziemliche Bedeutung bekommen. Insofern scheint Geschwindigkeit in vielen Anwendungsgebieten nicht gerade der wichtigste Punkt zu sein. Java bietet offensichtlich auch andere Dinge. Und unter diesem Gesichtspunkt sollte man die Performance von Javaprogrammen sehen. Heutzutage kommt man damit oft schon sehr in die Nähe von entsprechenden C++ Programmen, weil sich in der JVM in den letzten 10 Jahren eine Menge getan hat. Am Anfang waren Javaprogramme vielleicht um einen Faktor 100 langsamer als entsprechende C++ Programme. Heutzutage ist es in günstigen Fällen vielleicht nur noch ein Faktor 1,5 (und in Trivialfällen existiert teilweise fast gar kein Unterschied mehr). Wenn es um die Performance von Javaprogrammen geht, ist letztendlich die Frage, ob das ein entscheidender Nachteil in einem bestimmten Anwendungsgebiet ist. Das trifft heutzutage nur noch auf wenige Anwendungsgebiete zu. Trotz allem ist die Frage aus meiner Sicht nicht, ob Java da im Vorteil wäre. Wer soetwas für den allgemeinen Fall behauptet, nimmt die Realität wahrscheinlich etwas verzerrt wahr. Wer für einen bestimmten Anwendungsfall die optimale Performance braucht, wird auch in absehbarer Zukunft in erster Linie auf C++ setzen. Die Frage ist aber immer, ob man diese optimale Performance wirklich braucht.
-
Die Praxis zeigt sich aber das so ziemlich jedes Java-Programm zu langsam ist.
-
Zu langsam wofuer?
-
Für ein entspanntes Arbeiten mit dem Programm.
-
Ich habe vor einiger Zeit einen Forumbeitrag zu diesem Thema gefunden:
http://www.coding-board.de/board/archive/index.php/t-2096.html
-
Ich habe die Benchmarks mal selbst getestet und folgendes rausbekommen.
Please wait ...
Square Root: 48672 ms for 18 iterations; 2704 ms per iteration
Vector: 1984 ms for 100000000 iterations; 20 ns per iteration
List: 563 ms for 25000000 iterations; 23 ns per iteration
Blur: 437 ms for 4940180 iterations; 88 ns per iteration
Runge-Kutta: 500 ms for 500000 iterations; 1000 ns per iteration
Memory: 344 ms for 20000 iterations; 17200 ns per iterationC++
Please wait ...
Square Root: 15485 ms for 18 iterations; 860 ms per iterat
Vector: 125 ms for 100000000 iterations; 1 ns per iteratio
List: 157 ms for 25000000 iterations; 6 ns per iteration
Blur: 125 ms for 4940180 iterations; 25 ns per iteration
Runge-Kutta: 328 ms for 500000 iterations; 656 ns per iter
Memory: 79 ms for 20000 iterations; 3950 ns per iterationIm www.java-forum.org unter der Rubrik Performance im Thread "java und c++"
haben sie mir dieses Ergebnis präsentiert:
http://kano.net/javabench/graph
<img src="http://kano.net/javabench/graph">
-
Also hier an der Uni arbeietet Lehrstuhl 4 (www4.informatik.uni-erlangen.de) an einem Betriebsystem welches in Java geschrieben ist. http://www.jxos.org/
Die VM und der Compiler wurde selbst geschrieben.
Laut Aussage derer steckt im JavaBytecode so viel Wissen drin, dass man dadurch richtig gut optimiren kann.
Also deren (teilsweise) JustInTime-Compiler macht aus JavaByteCode gleich schnellen Assembler.Die nutzen also die guten Teile von Java und bringen es schnell auf die Maschine runter.
Also z.B. wird aus einer in Java geschriebenen MemoryMapMethode ein paar Brocken Assembler.Und durch die teilsweise extremen Optimierungen sind die - laut Aussage - manchmal auch schneller als C++.
-
@Gregor: Sehr guter Beitrag. Hast Du vielleicht auch noch Links bezüglich des JIT compilings? Also wie genau das funktioniert, denn schließlich muss ja der Maschinencode auch noch an die CPU weitergereicht werden? Werden komplette Methoden nativ übersetzt? Bei Sun konnte ich nur allgemeines zu diesem Thema finden.
-
@gregor schrieb:
Hast Du vielleicht auch noch Links bezüglich des JIT compilings?
Es gibt bei Sun ne ganze Menge zu deren "Hotspot-JVM":
http://java.sun.com/products/hotspot/
Ist sicherlich nicht in komprimierter Form das, was dich interessiert, aber da sollte trotzdem ne ganze Menge drinstehen, was Dich interessiert.
-
Gregor schrieb:
Blah blah blah!
Wieviel so ein paar nichtssagende Worte letztendlich doch sagen...
Gregor schrieb:
Es ist deshalb eine Verzerrung der Tatsachen, weil die JVM den Bytecode zur Laufzeit kompiliert.
Ach, und das kostet keine Zeit? Kannst du mir verraten, was für einen Rechner du hast? So einen möchte ich nämlich auch gerne haben.
Gregor schrieb:
Und da Du Performance meistens da brauchst, wo Du viel verarbeiten musst, kann dieser Aspekt eigentlich vernachlässigt werden.
Nein, ich habe von der kompletten Anwendung gesprochen. Und nicht nur von einzelnen Sequenzen.
Gregor schrieb:
Zudem können - wenn Du so prinzipielle Erwägungen machst - bei einer Kompilation zur Laufzeit bessere Optimierungen vorgenommen werden. Hier ist zum einen die genaue darunterliegende Plattform bekannt
Das ist bei einer Kompilation von C++ Programmen auch der Fall.
Gregor schrieb:
zum anderen ist aber auch der Zustand des Programms bekannt. Beide Aspekte könnten - vom Prinzip her
In einem gewissen statischen Rahmen ist C++ Compilern der Zustand des Programmes auch bekannt. Und "könnten" oder "vom Prinzip her" ist für mich keine logische Erklärung, wieso das zur Laufzeit vorteilhafter sein soll.
Zu 2. kann ich ehrlich gesagt nichts sagen, weil ich nicht weiss, worauf du dich beziehst. Aber bei Performancefragen über Generizität zu sprechen, ist leicht verfehlt. Mit Templates gewinnst du ja auch in C++ keine Performance. Dazu sind sie auch nicht da. Klar, sagt jetzt jemand, mit Template Meta Programmierung kann ich Sachen zur Kompilierungszeit schon berechnen und spar mir damit Laufzeit. Damit hat er natürlich Recht. Das ist aber nur eine spezielle Nutzung von Templates und für Java sowieso uninteressant, da, soweit ich weiss, Java nur Laufzeitgenerizität bietet.
Versteh mich nicht falsch, ich habe nicht geschrieben, dass C++ schnell ist und Java langsam. Auf dem Papier ist es aber erstmal so, dass mit Kompilersprachen schnellere Programme möglich sind als mit Interpretersprachen. Das ist Fakt, und liegt ganz einfach in der technischen Tatsache begründet, dass der "interpretierte" Code zur Laufzeit noch für die entsprechende Plattform verarbeitet werden muss. So die Theorie. Dass die Praxis aber ganz anders aussehen kann, wissen wir ja nun mittlerweile. Und bei einer aktuellen JVM sieht man, dass durch Optimierungen und gute Strategien Anwendungen mit absolut akzeptabler Geschwindigkeit laufen. Letztendlich hat das aber weniger mit der Sprache ansich zu tun, als vielmehr mit der Implementierung. Deshalb stören mich auch Sätze wie
Und durch die teilsweise extremen Optimierungen sind die - laut Aussage - manchmal auch schneller als C++.
Man kann die Geschwindigkeit von C++ nicht messen! Was man messen kann, sind Implementierungen. Deswegen aber Rückschlüsse auf _alle_ Implementierungen zu ziehen, ist schlichtweg Blödsinn.
-
Man kann es leider nicht oft genug sagen, da es manche immer noch nicht verstanden haben:
1.) Java ist für größere Client-Systeme(fat-clients) erheblich langsamer, was aber besonders durch den enormen Speicherverbrauch kommt(Hauptursache: Swing).
2.) Java ist die mit Abstand beste Sprache für Enterprise Lösungen. Dort kommen auch die von Gregor genannten Optimierungen ins Spiel. Klar ist der Programmstart und die ersten Abläufe durch das JIT langsamer, aber welche Rolle spielt das auf einem System was meistens ne Uptime von Monaten hat?
3.) Es gibt im Enterprise Bereich zu Java keine ernstzunehmende Konkurrenz. Das selbe gilt für browserbasierte Clients. Java hat für solche Systeme sehr gute Eigenschaften.
4.) Fakt bleibt weiterhin: Ein gleiches System wäre in C++ sicherlich minimal performanter(allein schon durch die vielen Speicherzugriffe von Java), aber welche Rolle spielt das in Zeiten wo ein Dual-Opteron System mit 4GB RAM keine 3.000 Euro mehr kostet? Dieser Preis ist für ein Unternehmen das solche Systeme betreibt ein Witz. Davon stellt man sich gerne 3 Stück hin. Was spielen da noch 5-10% Performance Einbußen für eine Rolle?
5.) Die Diskussion ist verallgemeinert einfach schwachsinn. Man kann nur ein genaues Einsatzgebiet vergleichen. In der professionellen Softwareentwickleung spielen viele andere Kriterien eine Rolle. 5-10% Performanceeinbußen gehören äussert selten dazu.
Alles andere ist wie Gregor schon sagte: "bla bla"
6.) Für Mainframes gibt es schon längst Co-Prozessoren die Java Bytecode nativ verstehen. Das unterstreicht wohl die Bedeutsamkeit von Java in riesigen Systemen!
-
Hi,
in diesem Zusammenhang sicherlich auch sehr interessant ist das Low Level Virtual Machine-Projekt (http://llvm.org/).
Damit kann- Währen der Compile-Time
- Während der Link-Time
- Während der Laufzeit
optimiert werden.
Damit könnte man evt. ziemlich gut messen, was eine virtuelle Maschine wirklich bringt.mfg,
pcmoritz.
-
Was meinste mit Enterprise?
-
Enterprise Architect schrieb:
6.) Für Mainframes gibt es schon längst Co-Prozessoren die Java Bytecode nativ verstehen. Das unterstreicht wohl die Bedeutsamkeit von Java in riesigen Systemen!
nicht nur für mainframes: http://www.ajile.com/products/aj100.htm
-
groovemaster schrieb:
Gregor schrieb:
Es ist deshalb eine Verzerrung der Tatsachen, weil die JVM den Bytecode zur Laufzeit kompiliert.
Ach, und das kostet keine Zeit? Kannst du mir verraten, was für einen Rechner du hast? So einen möchte ich nämlich auch gerne haben.
Die JIT-Compilierung ist doch einmalig. Wie soll sich das deiner Meinung nach negativ auswirken? Natürlich dauert der Programmstart u.U. länger, aber was soll's.
Gregor schrieb:
Und da Du Performance meistens da brauchst, wo Du viel verarbeiten musst, kann dieser Aspekt eigentlich vernachlässigt werden.
Nein, ich habe von der kompletten Anwendung gesprochen. Und nicht nur von einzelnen Sequenzen.
Du kennst aber die 80-20 Regel, oder?
Gregor schrieb:
Zudem können - wenn Du so prinzipielle Erwägungen machst - bei einer Kompilation zur Laufzeit bessere Optimierungen vorgenommen werden. Hier ist zum einen die genaue darunterliegende Plattform bekannt
Das ist bei einer Kompilation von C++ Programmen auch der Fall.
Nein.
Ein C++ Compiler kennt zur Compilier-Zeit nicht die dynamisch hinzugelinkten Bibliotheken -> Inlining adé!
Man compiliert auch nie 20 verschiedene Versionen für 20 Prozessoren (ich habe das noch nie gesehen). Stattdessen fasst man fast alle x86-Prozessoren in einem Build zusammen -> neue 32 Bit Register beim AMD64 adé, spezielle Berücksichtigung der weiteren Unterschiede adé.
Es gibt Variablen, die beim Programmstart nur einmal ausgelesen werden und sich amsonsten nicht mehr ändern. Ein C++ Compiler kann dies nicht nutzen.
Ein JIT-Compiler kann auch viel öfters feste Speicheradressen bilden, für die ein statische Compiler eine Indirektion einbauen muss. Das betrifft insbesondere die Fälle, wo man dynamisch was hinzulinkt.Ich schreibe immer "JIT-Compiler", der eigentliche Punkt ist aber auch, dass sämtliches Linking zur Laufzeit stattfindet. Das bringt erhebliche Vorteile beim hinzufügen von Laufzeit-Bibliotheken. Das Konzept der JIT-Compilierung ist insgesamt völlig überlegen. Es gibt genug theoretische Gründe, warum Java-Programme eigentlich schneller laufen müssten. Aber wie du schon festgestellt hast:
Was man messen kann, sind Implementierungen.
Wieviel so ein paar nichtssagende Worte letztendlich doch sagen...
Das kommt davon, wenn man Märchen mit Interpretieren des Bytecodes erzählt. Das ist seit ~10 Jahren schon nicht mehr Stand der Technik.