performant Java programmieren



  • Stummi schrieb:

    Speichereffizient wirst du mit Java nicht programmieren können

    Warum sollte man mit java nicht speichereffizent programmieren können ?

    @pr0gg4
    Es kommt immer drauf an WAS genau du programmieren willst. Du musst halt etwas anderes denken als wenn du C oder C++ programmierst.
    Un auch wenn es so ein paar Regeln gibt an die man sich halten sollte, würde ich erst wirklich optimieren wenn es einen Flaschenhals gibt.

    Aber zum Beispiel auch nicht einfach die Speicherverwaltung komplett vernachlässigen nur weil es einen GC gibt. Wenn du zum Beispiel immer wieder unmengen an neuen Objekten erstellst statt sie zu recycelst (Object Pool) ist das nicht gerade performant.
    Oder Java Funktionen verwenden statt eigene zu basteln.
    Die Laufzeitperformance von Javaprogrammen ist ansich gar nicht so schlecht, zumindest wenn man keinen schlechten Code schreibt. Kann schon sein dass man mit Java im vergleich zu C++ bei number crunching schlechter abschneidet, aber zur not kann man ja immernoch mit JNI nativen code nutzen.

    Mal ein paar Dinge die den Code deutlich schneller machen können:

    • Java Funktionen verwenden statt eigener Konstrukte, z.B. arraycopy() statt eines for loops
    • Stringbuilder statt direkter Stringverknüpfung
    • Objekte recyceln
    • generell so wenig new wie möglich (wenn es denn performancekritisch ist)
    • Reflection vermeiden
    • Exceptions vermeiden

    Das ist eine recht willkürliche Liste, aber ich denke die wichtigsten Dinge sind drin. Wenn ich Performanceoptimierungen mache dann sind die Probleme meistens
    a) Objekte die den GC zuspammen (also Pool oder ganz umschreiben)
    b) Inperformance Spielereien mit strings, wobei das auch meistens einfach den GC zuspammt

    Und ansonsten einfach nachdenken ob es nicht einfacher geht. Wenn du nen besseren Algorithmus hast hilft das meistens deutlich mehr als irgendwelche Optimierungen, außer du hast wirklich inperformanten Code. 😉


  • Mod

    DarkShadow44 schrieb:

    Wenn ich Performanceoptimierungen mache dann sind die Probleme meistens
    a) Objekte die den GC zuspammen (also Pool oder ganz umschreiben)
    b) Inperformance Spielereien mit strings, wobei das auch meistens einfach den GC zuspammt

    Bei mir sind die Probleme meistens das Hantieren mit Unmengen an sehr kleinen Objekten. Das Problem dabei ist, dass es in Java im Vergleich zu C++ fuer jedes Objekt einen erhoehten Speicherverbrauch von 8 Byte gibt. Wenn man sehr viele kleine Objekte hat, die selbst jeweils nur ganz kleine Datenmengen enthalten (zum Beispiel ein einzelnes int), dann ist man schnell an einer Stelle, an der bei Java ein Cache nicht mehr ausreicht, der bei C++ noch gross genug ist. Ich wuerde an performancekritischen Stellen deshalb sehr genau darauf achten, so etwas zu verhindern.



  • DarkShadow44 schrieb:

    Stummi schrieb:

    Speichereffizient wirst du mit Java nicht programmieren können

    Warum sollte man mit java nicht speichereffizent programmieren können ?

    Weil jedes einzelne Objekt, welches in der JVM erzeugt wird, einen Overhead von ein paar Byte hat. Dies mag erstmal nicht viel klingen, macht sich in der Masse aber durchaus bemerkbar. Eine HashMap beinhaltet z.B. intern ein Objekt pro Eintrag, genauso wie eine LinkedList.

    Vielleicht war "geht nicht" auch falsch ausgedrückt, es ist auf jedenfall wesentlich schwieriger als z.B. in C weil du auf die Speicherverwaltung kaum bis keinen Einfluss hast.



  • Gregor schrieb:

    Bei mir sind die Probleme meistens das Hantieren mit Unmengen an sehr kleinen Objekten. Das Problem dabei ist, dass es in Java im Vergleich zu C++ fuer jedes Objekt einen erhoehten Speicherverbrauch von 8 Byte gibt. Wenn man sehr viele kleine Objekte hat, die selbst jeweils nur ganz kleine Datenmengen enthalten (zum Beispiel ein einzelnes int), dann ist man schnell an einer Stelle, an der bei Java ein Cache nicht mehr ausreicht, der bei C++ noch gross genug ist.

    Stimmt schon, aber man kann ja wie gesagt das Programm auch noch umschreiben um solche Probleme zu umgehen.
    Ich denke das Problem bezüglich der Speicherperformance ist einfach dass es Java sehr einfach macht sehr Speicherverschwenderisch zu programmieren.
    Wenn man sich nicht bewusst ist wie die Speicherverwaltung funktioniert wird es schwer den Speicher performant zu nutzen.

    Stummi schrieb:

    es ist auf jedenfall wesentlich schwieriger als z.B. in C weil du auf die Speicherverwaltung kaum bis keinen Einfluss hast.

    Naja, man kann wie gesagt auch Objekt-Pools und andere Tricks verwenden um den Speicher "manuell" zu verwalten, man darf nur nicht von C auf Java schließen.



  • Naja, eigentlich ist das Argument gegen C++, das man sich um Speicher selber kümmern muss.

    Und deshalb werden ja GC-Sprachen immer so in den Vordergrund gestellt.

    Auf Arbeit mache ich es tatsächlich so, das ich mich um die Speichermenge nicht kümmere. Ich programmiere so, das mein Code wartbar bleibt und der Rest soll vom GC und RAM-Aufrüsstung erledigt werden. Der Kunde will Java? Soll er bekommen! Er bezahlt mich auch nicht dafür, das ich mich mit Nebenkriegsschauplätzen beschäftige. Die Aufgabe soll erfüllt werden. Wenn der User-PC oder Server zu wenig Speicher hat, wird mehr RAM eingebaut. Ist billiger für alle Beteiligten. (zusätzlicher RAM-Riegel oder mehrere Stundensätze? einfache Entscheidung)

    Wenn der Kunde wollen würde, das ich mich um Speicher kümmere, würde er das Projekt in C++ implementieren lassen und auch bereit sein entsprechende Nebenarbeiten zu bezahlen.

    Und das meine ich alles nicht mal abwertend ggü. Java & Co. Es ist völlig legitim so zu handeln. 🙂

    PS: Lediglich auf Embedded-Systemen (wie Smartphones), wo keine Aufrüstung möglich ist, kann man nochmal über Massnahmen nachdenken. Aber auch hier: wenn kein RAM da ist, ist halt Schluß! Dann wird halt geswappt o.ä.



  • Artchi schrieb:

    Naja, eigentlich ist das Argument gegen C++, das man sich um Speicher selber kümmern muss.
    Und deshalb werden ja GC-Sprachen immer so in den Vordergrund gestellt.

    Eher aus historischen Gründen: Weil Java mit diesem Werbefeldzug so erfolgreich war.

    Habe gerade ein Projekt in Ruby angefangen (dort waren die Bibliotheken leicht verfogbar). Uups, keine Destruktoren für Volkard. Ich habe einfach keine Zeit, alles per Hand zu machen, was Destruktoren automatisch machen wollen, deshalb schaue ich mich nach einer anderen Sprache um (und wenns Perl wird).



  • volkard schrieb:

    Habe gerade ein Projekt in Ruby angefangen (dort waren die Bibliotheken leicht verfogbar). Uups, keine Destruktoren für Volkard. Ich habe einfach keine Zeit, alles per Hand zu machen, was Destruktoren automatisch machen wollen, deshalb schaue ich mich nach einer anderen Sprache um (und wenns Perl wird).

    Du musst auch nicht in jeder Programmiersprache C++ programmieren wollen.



  • stagnatiker schrieb:

    volkard schrieb:

    Habe gerade ein Projekt in Ruby angefangen (dort waren die Bibliotheken leicht verfogbar). Uups, keine Destruktoren für Volkard. Ich habe einfach keine Zeit, alles per Hand zu machen, was Destruktoren automatisch machen wollen, deshalb schaue ich mich nach einer anderen Sprache um (und wenns Perl wird).

    Du musst auch nicht in jeder Programmiersprache C++ programmieren wollen.

    Doch, zumindest bzgl. Destruktoren.
    Das Konzept ist einfach so gut, dass Java, C# & co verzweifelt versuchen, dass nachträglich via try-catch-with-resources nachzubauen.



  • Jockelx schrieb:

    stagnatiker schrieb:

    volkard schrieb:

    Habe gerade ein Projekt in Ruby angefangen (dort waren die Bibliotheken leicht verfogbar). Uups, keine Destruktoren für Volkard. Ich habe einfach keine Zeit, alles per Hand zu machen, was Destruktoren automatisch machen wollen, deshalb schaue ich mich nach einer anderen Sprache um (und wenns Perl wird).

    Du musst auch nicht in jeder Programmiersprache C++ programmieren wollen.

    Doch, zumindest bzgl. Destruktoren.
    Das Konzept ist einfach so gut, dass Java, C# & co verzweifelt versuchen, dass nachträglich via try-catch-with-resources nachzubauen.

    Oder mit einem lächerlichen Dispose().



  • stagnatiker schrieb:

    volkard schrieb:

    Habe gerade ein Projekt in Ruby angefangen (dort waren die Bibliotheken leicht verfogbar). Uups, keine Destruktoren für Volkard. Ich habe einfach keine Zeit, alles per Hand zu machen, was Destruktoren automatisch machen wollen, deshalb schaue ich mich nach einer anderen Sprache um (und wenns Perl wird).

    Du musst auch nicht in jeder Programmiersprache C++ programmieren wollen.

    Leider gibt es kein anderes, ähnlich mächtiges Konzept zur Ressourcenverwaltung; zumindest ist mir keine Lösung bekannt, die RAII auch nur ansatzweise das Wasser reichen kann. Falls du eine kennst, wäre ich sehr interessiert, mehr zu erfahren.


Anmelden zum Antworten