Software Tuning

Allgemein

  • jegliche Art von Redundanzen im Quelltext vermeiden
    • schlecht: x = a * b + m; y = a * b + n;
    • gut: ab = a * b; x = ab + m; y = ab + n;
  • innere Klassen sind langsamer als äußere Klassen
  • lokale Variablen sind schneller als globale Variablen
  • bei Verwendung von mathematischen Methoden prüfen, ob eigene Programmierung schneller ist (vorgegebene Klassen sind nicht immer Performance-optimiert!)
  • private Methoden und als final deklarierte Variablen werden nicht aufgerufen, sondern der Byte-Code an die Stelle des Aufrufs kopiert daher schneller → aber mit größerem Speicherbedarf, also: wenn etwas private/final sein darf, dann sollte man es auch so machen!
  • Inlining verwenden, wenn möglich, um die Länge des Byte-Codes zu optimieren

Inkrement und Dekrement

  • Inkrement und Dekrement anstatt Berechnung verwenden
  • x++; ist schneller als x+=1; oder x = x + 1;
  • Prädekrement ist schneller als Postdekrement und Präinkrement ist schneller als Postinkrement (--i; ++i; ist schneller als i--; i++;)
  • Dekrement ist schneller als Inkrement

Datentypen

  • Verwendung der richtigen, schnellen und passenden Datentypen
    • Beispiel: wenn keine Berechnungen mit Bruch auftreten, dann keine Fließkomma-Variablendatentypen verwenden (int statt double oder float)
    • Beispiel: wenn nur kleine Zahlen auftreten, Notwendigkeit großer Zahlen-Variablendatentypen prüfen (short statt int oder long)
  • alle Arten von Überlängen vermeiden (zu große Datentypen, zu groß initialisierte Arrays usw.)
  • beim Schreiben und Lesen von Dateien am besten Puffer benutzen
  • BufferedReader und BufferedWriter anstatt FileReader und FileWriter
  • Casten von Datentypen vermeiden (fehleranfällig und performanceintensiv)
  • mehrdimensionale Felder vermeiden
  • bei Zugriff auf mehrdimensionale Felder zuerst auf die Felder zugreifen, die die wenigsten Elemente besitzen
  • String-Verkettung mit + sehr performanceintensiv, besser mit StringBuffer-Objekt, oder den im Objekt String zur Verfügung stehenden Methoden (concat, substr)
  • mit festem Wert initialisierter StringBuffer ist am schnellsten (bis zum 100fachen), jedoch Überlauf beachten!
  • String-Vergleich mit .equals und nicht mit ==
  • Datentypen 2. Klasse (boolean, byte, short, char) performanter als Datentypen 1. Klasse (int, long, float, double)

Berechnungen

  • Index-Berechnungen vermeiden
  • Bitverschiebung ist immer schneller als Berechnung
    • y = x » 1; ist schneller als y = x / 2;
  • Berechnungen von Werten, die ohnehin konstant sind, gleich als Ergebnis in die Konstante speichern und nicht im Quelltext berechnen lassen, auch wenn es besser aussieht

Verzweigungen (if und switch)

  • bei if-Verzweigungen || anstatt | verwenden, weil dadurch die zweite Bedingung nicht mehr geprüft wird, wenn bereits die erste true/false war (| ist schlechter)
  • jede Art von boolschen Ausdrücken so weit wie möglich vereinfachen
  • Verzweigungen mit der größten Wahrscheinlichkeit sollten zuerst stehen, sowohl bei if, als auch bei switch
  • bei Mehrfachbedingungen sollte ein vorzeitiger Abbruch möglich sein
    • Beispiel: if() … else if() … else if() … anstatt if() …; if() …); if()…;

Schleifen (for, do, while)

  • Schleifen lieber mit break verlassen/beenden, anstatt einer boolean-Variable, die geprüft wird, gilt auch für for-Schleifen!
  • alle unnötigen Anweisungen aus Schleifenkörpern herausholen
  • Schleifen können ausgerollt bedeutend performanter sein, obwohl der Quelltext länger ist
    • Beispiel: for-Schleifen mit < 10 Durchläufen ist es besser jede Anweisung manuell zu schreiben
  • Anzahl der Schleifendurchläufe so gut es geht verringern z.B. for-Schleife mit 100 Durchläufen auf 10 verkürzen, dafür in den Körper 10 Anweisungen mit der Schleifeninvariante +1, +2, +3 usw.
  • Funktionsaufrufe in Schleifenköpfen (Bedingungsprüfungen) vermeiden
    • schlecht: for(int i=0; i < array.size(); i++) …; weil jedes mal .size() ausgeführt wird
    • gut: int size = array.size(); for (int i=0; i < size; i++) …; weil nur einmal .size() ausgeführt wird
  • rekusive Schleifen sind tendenziell langsamer als iterative Schleifen
  • kleinere Schleifen nach außen verlagern
  • Zuweisungen zu Arrays über temp-Werte schneller als ständiger Zugriff auf das Array
    • Beispiel: wenn aus dem Array nur ein Wert verwendet wird, dann diesen in eine temp- Variable auslagern, die temp-Variable in der Schleife bearbeiten/verändern und dann nach verlassen der Schleife das Ergebnis in das Array zurück schreiben
  • bei while ist Berechnung der Schleifeninvariable im Schleifenkörper schneller als im Schleifenkopf
  • bei do ist Berechnung der Schleifeninvariable im Schleifenkopf schneller als im Schleifenkörper

Kontext

Weiterführende Beiträge


Navigation

Alphabetischer Index
Akronyme