Plugin mit guter Performance programmieren

  • Hallo,

    ich hätte da mal eine Frage, und zwar: Wie programmiert man ein performantes Plugin? Was zieht zum Beispiel am meisten Leistung? Welcher Programmier-Stiel ist besonders gut/schnell/performant? Welche Dinge sollte man vermeiden? Vielleicht weiß ja jemand etwas darüber. ^^

    MfG
    TheGaming

  • Grundsätzlich gilt immer je näher dein Code an "Basis Code" ist desto performanter ist dieser. (Ausnahmen gibt es).


    Rechenoperationen - einfache Regel

    a) Je komplizierter die Rechnung desto länger braucht Java (1523³³)


    Zum selbst Testen:


    Output (hängt von CPU, etc ab):

    Code
    4
    Operation needed : 736
    1073741824
    Operation needed : 25
    1.0692932125168965E105
    Operation needed : 1623


    Zeichenketten - ! Ausnahme !

    Dazu einfach mal diesen Artikel anschauen. Das Interessanteste bei Punkt 4


    Schleifen - sind immer ein Performance Killer durch

    a) große Anzahl an Durchläufen

    b) Komplizierte verschachtelte Operationen im Inneren


    Einfacher Logischer Gedanke:


    Aufgabe 1: 15x mal "Hello, World" ausgeben

    Aufwand: quasi null


    Aufgabe 2: 15x mal 1.000.000 / 23 rechnen dann das Ergebnis In eine Datei schreiben und zuguterletzt ausgeben

    Aufwand: hoch


    Zum selbst Testen:

    Output (hängt von CPU, etc ab):

    Code
    Operation needed : 866
    Operation needed : 15237

    Nun sollte klar sein je komplizierter der Code bzw die Aufgabe die er erfüllen soll desto länger wird Java dafür brauchen das Ganze auszuführen.

    If you are homeless ... just buy a house, duh!

    and if you wanna have a plugin matching your conditions ... just code it yourself!

  • Ein bisschen Verständnis von Compilern wäre auch ganz gut.

    Zum Beispiel: Schleifen werden, insofern sie nicht zu oft durchgehen, unrolled also automatisch einfach kopiert vom Inneren her.

    Somit muss ein Programmierer das nicht selbst tun, was bei der nötigen Anzahl keinen Sinn mehr macht, wenn der Compiler das schon nicht macht.


    Im Bezug auf Java kann ich zudem sagen, dass man beim GC aufpassen muss: erstellst du sehr sehr viele Objekte innerhalb kurzer Zeit, bringt das den GC zum Ausrasten und damit deine CPU auf oft sogar Vollast.


    Ein weiterer Aspekt ist z.B. Inlining: Methoden, die unter 30 Instruktionen lang sind, werden in der Regel sehr schnell von einer VM inlined und sind damit genauso schnell als wenn man den Code kopiert hätte, statt eine Methode zu schreiben.


    Das bringt uns zum nächsten Punkt: Methoden calls sind sehr aufwendig. Sie ziehen bei manchen Applikationen einen beträchtlichen Anteil der Zeit, da alle Register etc., Je nach Architektur und Betriebssystem, geleert bzw rumgeschoben werden müssen um den Method Parametern zu entsprechen.


    Ich würde noch mehr schreiben, aber ich bin gerade am Handy und das ist recht lästig.


    //EDIT: Bin jetzt am PC


    Wenn du auf Ram achten willst, dann empfehle ich dir, dass du dir Gedanken über häufig verwendete Objekte und deren Größe machst:

    Jedes Objekt in Java hat einen 8byte großen Header, welcher den Typ des Objekts und einige Flags beinhaltet.

    Zudem sind alle Daten in Java 8byte aligned. Doch was heißt das?
    Ganz einfach: moderen Prozessoren lesen nicht mehr nur ein einzelnes Byte aus dem Arbeitsspeicher, sondern sogenannte "Words" diese sind oft 4 oder 8 bytes, je nach Architektur.

    Somit kann ein Prozessor mit nur einem einzelnen Zugriff immer 4/8 bytes lesen, egal ob benötigt oder nicht.

    Wenn man jetzt 4 bytes in einem Objekt hat, kann der Prozessor diese mit einem Zugriff (theoretisch) lesen.

    Würde man nicht alignen, würde man zwangsläufig auf das Problem stoßen, dass diese 4 bytes (oder andere Variationen) direkt auf der "Kante" liegen und damit 2 Zugriffe benötigt werden, da der Prozessor nur bei einem Vielfachen von 4/8 anfangen kann zu lesen.


    Des Weiteren ermöglicht das Alignen von Objekten CompressOops, also dass Pointer auf Objekte nur 4 bytes groß sind.

    Weil auch "Referenzen" in Arrays und Objekten benötigen ja Ram um den Pointer zu halten.

    Und bei 64bit Maschinen wären das 8 bytes pro Pointer. Dies kann man aber minimieren durch CompressedOops, welches aber nur durch Alignment möglich wird.


    Btw: Arrays sind in Java auch Objekte, welche einen 8bytes Header + 4bytes Größe beinhalten.


    Ein weiterer CPU Killer wäre die Konsole: In manchen Benchmarks wird direkt das Ergebnis ausgegeben. Damit misst man aber nicht die Berechnung, sondern größtenteils den Overhead des Sysouts.

    Das Gleiche gilt für Schleifen: eine simple Addition in Schleifen zu packen und danach außerhalb der Schleife zu messen macht keinen Sinn, da die Schleife bereits Sprünge, Vergleiche und Additionen beinhaltet.


    Wenn du interessiert bist, kann ich dir auch noch ein bisschen was zu Pipelines etc. erzählen und Compiler Optimierungen, die man von Hand begünstigen kann.