Wäre Java schneller mit anderer Speicherverwaltung?



  • Wäre Java viel schneller, wenn es keinen GC gäbe, aber man dafür auch Objekte auf dem Stack anlegen könnte?



  • yoomoonoo schrieb:

    Wäre Java viel schneller, wenn es keinen GC gäbe, aber man dafür auch Objekte auf dem Stack anlegen könnte?

    1. Der GC ist _sehr_ schnell. Ich behaupte mal einfach so, dass die Nutzung von Speicher auf dem Heap in Java locker mit der Nutzung von Speicher auf dem Heap in einer Sprache wie C++ oder so mithalten kann.

    2. Der Stack ist aber natürlich deutlich schneller als der Heap und da hat man mit anderen Sprachen eben mehr Möglichkeiten als mit Java. Wenn Du größtenteils auf Speicheroperationen in Bezug auf den Heap verzichten kannst, dann beschleunigt das Dein Programm in jeder Sprache (natürlich nur dann, wenn die Speicheroperationen überhaupt einen signifikanten Anteil an der Performance des jeweiligen Programms haben). Entsprechend würde Java auch davon profitieren, wenn man Objekte auf den Stack legen könnte.

    3. Prinzipiell wäre es durchaus möglich, die JVM entscheiden zu lassen, wo ein Objekt abgespeichert werden sollte oder entsprechende explizite Mechanismen in die Sprache einzubauen. Diesbezüglich gibt es übrigens ein paar RFEs. Mal abwarten, ob da irgendwann mal etwas bei rauskommt. Ich habe momentan nicht das Gefühl, dass diesbezüglich ein ernsthafter Wille bei den Javaentwicklern existiert.

    EDIT: Da ist ein ganz interessanter Artikel dazu: http://www.ibm.com/developerworks/java/library/j-jtp09275.html



  • yoomoonoo schrieb:

    Wäre Java viel schneller, wenn es keinen GC gäbe, aber man dafür auch Objekte auf dem Stack anlegen könnte?

    Klar. Aber die Javaler haben schon gelernt, wie sie das Erzeugen von Objekten vermeiden können... manche rufen sogar zur Laufzeit den Compiler auf, um entsprechenden dicht gepackten Code zu erzeugen.



  • Java ist so schnell, dass es jedem Programmierer, der nicht absoluten Bockmist programmiert, ausreichen sollte.



  • Naja wenn man simple nich zeitkritische schicky-micky tools bzw Anwendungen coded schon;)

    Schnell ist relativ. Man kann auch mit elegant programmierten code in java, niemanls die effizenz bspw. von C/C++ rausholen. Wenn man Speed braucht, recht es nicht aus in Java guten code zu schreiben.



  • du hast noch nicht viel software entwickelt, oder? das, was den großteil der anwendungen da draussen, bremst, ist nicht die sprache oder die effizienz der programmierung. die meisten anwendungen werden durch zugriffe auf massenspeicher ausgebremst, ob das nun dateizugriffe, datenbanken oder sonstwas ist, spielt keine rolle. in dem bereich hab ich schon sehr viele anwendungen in diversen sprachen geschrieben und die performance konnte man im endeffekt dann tatsächlich nur noch ausschließlich von der effektivität des codes ausmachen. bei direkten portierungen von c++ in java code konnte ich absolut null unterschied feststellen. und wie das so ist: meist war der c++ code alt, der java code neu und siehe da... java wurde doch schneller :p



  • yoomoonoo schrieb:

    Wäre Java viel schneller, wenn es keinen GC gäbe, aber man dafür auch Objekte auf dem Stack anlegen könnte?

    In den JVM gab es ueber die zeit viele verschiedene GC implementierungen. Jede davon hat irgendwo vorteile und woanders nachteile. z.B. gab es ein GC der zwei speicherbereiche hatte und von zeit zu zeit alle referenzierten objekte umkopierte. hast du nicht gerade einen riesen speicherverbrauch, sollte es keine probleme geben. hast du kurzzeitig sehr zeitkritische funktionen die zudem sehr ausgefallene datenstrukturen haben bei denen es nicht trivial ist die lebenszeit eines objektes zu tracken (damit man es deleted wenn's noetig ist), kann dieser GC dir geschwindigkeitsvorteile bieten gegenueber eine "normalen" speicherverwaltung, wenn du unmengen allokierst und freigibst.

    fast alle GCs die in VMs verwendet defragmentieren den speicher, was zusaetzliche vorteile bieten kann.

    leider hat das ganze ja auch grosse nachteile, geschwindigkeit ist ja nicht gleich geschwindigkeit. eventuell moechtest du kurzzeitig zeitkritische dinge erledigen, eventuell liegt dir etwas an sehr konstanter guter geschwindigkeit mehr als an peak werten etc.
    da schlaegt das echte uebel zu, von VM zu VM verhaelt sich das bei Java anders, du hast keinen verlass. es kann sein dass im hintergrund durchgaengig der gc arbeitet, es kann sein dass er in grossen zeitabstaenden einschlaegt. (ein grund weshalb die meisten GC es erlauben explizit 'hints' an die GC zu geben).

    Man sollte aber bedenken dass der sinn von einem GC einfacherere programmierung ist. soeine generische loesung wird im schnitt nicht so schnell sein wie eine gut programmierte explizite speicherverwaltung. aber mein 500ps trecker kann auch meinen 400ps ferrari nicht einholen.



  • ein GC hat im normalfall eine viel schnellere speicherallozierung. Wie im obigen link beschrieben, wird normalerweise nur der pointer auf den freien speicher nach einer allozierung erhöht.
    Also wird keine zeit fürs suchen von freien speicher verwandt, wie das bei traditionellen heaps der fall ist. Nur wird durch die zufällig auftretende GC einmalig der programmablauf unterbrochen. Das sollte aber kein problem sein, da normale programme wegen des multitaskings sowieso unterbrochen werden...



  • Gibt's eigentlich irgendwo realistische Benchmarks z.B. "generational GC" vs. "traditional malloc/free"? Schnelle Implementierung von beiden vorausgesetzt, und ein Testprogramm welches dazu führt dass der GC mehrfach laufen muss?

    "Idioten-Benchmarks" hab' ich schon einige gesehen - bloss wenn man z.B. so wenig Speicher anfordert dass der GC erst garnie losläuft ist es kein Wunder wenn die GC Version schneller ist. Oder wenn man einen auf Geschwindigkeit getrimmten GC mit der MSVC malloc/free Implementierung vergleicht... naja, auch kein Wunder dass der GC besser abschneidet als "die wohl langsamste malloc/free Implementierung der Welt".



  • Ich sagte Schnell ist relativ, Aufwendige berechnung algorithmen arbeiten im normalfall mit dem physikalischen Speicher. Da lässt sich in C/C++ einfach mehr performance rausholen...



  • hustbaer schrieb:

    "Idioten-Benchmarks" hab' ich schon einige gesehen - bloss wenn man z.B. so wenig Speicher anfordert dass der GC erst garnie losläuft ist es kein Wunder wenn die GC Version schneller ist. Oder wenn man einen auf Geschwindigkeit getrimmten GC mit der MSVC malloc/free Implementierung vergleicht... naja, auch kein Wunder dass der GC besser abschneidet als "die wohl langsamste malloc/free Implementierung der Welt".

    Gab hier vor Jahren mal einen Test wo C++ gnadenlos abgestunken hat, dann etwas später (glaub 1-2Jahre) hatte Volkard eine C++ Variante vorgestellt welche Java deutlich überlegen war. Der Grund warum es so lange ging: Volkard hatte erst dort das Wissen dazu, damit solltet ihr eine Vorstellung haben wie aufwendig es war in C++ eine effizientere Speicherverwaltung zu realisieren wie die JVM hat(te).

    Vielleicht existiert der Thread ja noch, falls ja bitte hier verlinken, würd ihn auch gerne nochmals lesen.



  • rapso schrieb:

    yoomoonoo schrieb:

    Wäre Java viel schneller, wenn es keinen GC gäbe, aber man dafür auch Objekte auf dem Stack anlegen könnte?

    Man sollte aber bedenken dass der sinn von einem GC einfacherere programmierung ist. soeine generische loesung wird im schnitt nicht so schnell sein wie eine gut programmierte explizite speicherverwaltung. aber mein 500ps trecker kann auch meinen 400ps ferrari nicht einholen.

    Genau so sehe ich das auch. Ich verbringe meine Tage ja auch nicht damit den Compiler vpn C++ zu optimieren, sondern ueberlasse das den Compiler-Entwicklern. In Java mit dem GC ueberlass ich die Speicherverwaltung dem GC und damit den JVM-Entwicklern. Die werden dafuer bezahlt das sie die JVM optimieren, ich werde dafuer bezahlt Anwendungen zu schreiben.

    Mal ehrlich, wer hat hier schonmal in C++ sein eigenen Speichermanagment geschrieben und wer davon war damit besser als die jeweilige new/delete/malloc/free Implementierungen des Compilers?

    rapso schrieb:

    leider hat das ganze ja auch grosse nachteile, geschwindigkeit ist ja nicht gleich geschwindigkeit. eventuell moechtest du kurzzeitig zeitkritische dinge erledigen, eventuell liegt dir etwas an sehr konstanter guter geschwindigkeit mehr als an peak werten etc.
    da schlaegt das echte uebel zu, von VM zu VM verhaelt sich das bei Java anders, du hast keinen verlass. es kann sein dass im hintergrund durchgaengig der gc arbeitet, es kann sein dass er in grossen zeitabstaenden einschlaegt. (ein grund weshalb die meisten GC es erlauben explizit 'hints' an die GC zu geben).

    Das ist doch der Vorteil einer JVM. Man kann je nach Bedarf den GC austauschen ohne das Programm neu uebersetzen zu muessen. Bzw. man tauscht einfach die JVM aus oder liefert eine angepasste mit. Es gibt ja auch Realtime-Java http://java.sun.com/javase/technologies/realtime/



  • DEvent schrieb:

    Es gibt ja auch Realtime-Java http://java.sun.com/javase/technologies/realtime/

    Immortal memory holds objects without destroying them except when the program ends. This means that objects created in immortal memory must be carefully allocated and managed.



  • Mal ehrlich, wer hat hier schonmal in C++ sein eigenen Speichermanagment geschrieben und wer davon war damit besser als die jeweilige new/delete/malloc/free Implementierungen des Compilers?

    Boost. Ich hab mal ne Liste in der viel eingefügt wurde um locker faktor 20 verschnellert, indem ich den boost allokator genommen hab der auf kleine Objekte optimiert ist.



  • übrigens gings anfangs ja auch darum in Java Objekte auf dem Stack anlegen zu können, was ja immer schneller geht als new, weil man nie speicherbereiche suchen oder aufräumen muss.



  • @DEvent:
    Du kannst aber einen Allocator wie tcmalloc verwenden, der ordentlich auf Geschwindigkeit optimiert ist. Und einen Allocator wie den vom MSVC (bzw. HeapAlloc/HeapFree) zu übertreffen (was Geschwindigkeit angeht) ist nicht sonderlich schwer.

    @WasIstSchnell: du bist ja ein ganz Schlauer. Es gibt genug Software die CPU limitiert ist.
    Gerade wenn "schön" programmiert wird sind Dinge wie ein guter Optimizer und ein schneller Allocator wichtig.

    @Wiss0r: Welchen Allocator hat die C++ Variante verwendet? Ohne diese Angabe ist der Hinweis ziemlich wertlos.



  • DEvent schrieb:

    Das ist doch der Vorteil einer JVM. Man kann je nach Bedarf den GC austauschen ohne das Programm neu uebersetzen zu muessen.

    es ist sicher kein vorteil wenn der entwickler sich nicht auf das laufzeitverhalten eines GC verlassen kann... wie ich schon sagte.



  • Wiss0r schrieb:

    Vielleicht existiert der Thread ja noch, falls ja bitte hier verlinken, würd ihn auch gerne nochmals lesen.

    http://www.c-plusplus.net/forum/viewtopic-var-t-is-70097-and-start-is-0.html



  • raps schrieb:

    DEvent schrieb:

    Das ist doch der Vorteil einer JVM. Man kann je nach Bedarf den GC austauschen ohne das Programm neu uebersetzen zu muessen.

    es ist sicher kein vorteil wenn der entwickler sich nicht auf das laufzeitverhalten eines GC verlassen kann... wie ich schon sagte.

    das ist aber einer der grundsätze, nach denen man in java handeln sollte. der GC kann sonstwie implementiert sein und man sollte sich erstens nicht darauf verlassen, dass er in irgendeiner bestimmten art und weise arbeitet und zweitens sollte man sogar nichtmal versuchen, den GC zu überlisten.

    hab mal ein schönes beispiel gesehen, das zeigt, wie sehr man in java auf die nase fallen kann, wenn man versucht, schlauer als der GC zu sein. ging um eine bestimmte variante des object poolings. der code wurde durch pooling in der sun 1.1 jvm geringfügig schneller. mit einer neueren jvm version war der code allerdings um mehr als faktor 10 langsamer, als ein code vollständig ohne pooling.

    in java ist ein "new" tatsächlich nichts böses, solange die objekte nur kurz genug existieren.



  • raps schrieb:

    DEvent schrieb:

    Das ist doch der Vorteil einer JVM. Man kann je nach Bedarf den GC austauschen ohne das Programm neu uebersetzen zu muessen.

    es ist sicher kein vorteil wenn der entwickler sich nicht auf das laufzeitverhalten eines GC verlassen kann... wie ich schon sagte.

    Doch, denn Java wird wohl zum größten Teil für Business und Enterprise Applications eingesetzt. Dort interessiert man sich idR nicht für das Laufzeitverhalten des GC, weil die Flaschenhälse ganz woanders liegen (meistens bei der Datenbank).

    Und wo die Geschwindigkeit des GC nicht ausreichend ist, setzt man halt kein Java ein. Der prozentuale Anteil der Software, wo das der Fall ist, dürfte aber recht gering sein (hardwarenahe Programmierung mal ausgeschlossen).



  • Konfuzius sagt: Ein Weg zu kennen, ist nicht dasselbe wie Ihn zu gehen.


Anmelden zum Antworten