Die Präsentation wird geladen. Bitte warten

Die Präsentation wird geladen. Bitte warten

Java Performance Tuning Performance Tuning is similar to playing a strategy game but happily you usually get paid for it.

Ähnliche Präsentationen


Präsentation zum Thema: "Java Performance Tuning Performance Tuning is similar to playing a strategy game but happily you usually get paid for it."—  Präsentation transkript:

1 Java Performance Tuning Performance Tuning is similar to playing a strategy game but happily you usually get paid for it.

2 Bernhard MährJava Performance Tuning2/25 Schlechte Performanz kaschieren Eigentlich kein Tuning Benutzer findet das Programm schnell Responsabiltiy Trennung von UI und Arbeits-Thread Animationen um Wartezeiten zu verkürzen siehe zB Fading-Effekte in WindowsXP Vorarbeiten zB während Texteingaben durchführen gibt dem Benutzer das Gefühl einer blitzschnellen Anwendung

3 Bernhard MährJava Performance Tuning3/25 Allgemeines Sollte erst an der fertigen Anwendung durchgeführt werden Performance Tuning widerspricht meist objektorientiertem Design Code wird unübersichtlicher Aber: Beim Application-Design Performance nicht ignorieren Änderungen können auf anderen Platformen Performanz-Nachteile bringen Neusten Compiler verwenden

4 Bernhard MährJava Performance Tuning4/25 Schritte 1. Benchmark einbauen und Tests ausführen 2. Bottlenecks identifizieren 3. Eines aus den Top 5 Bottelnecks wählen (abhängig von bremsender Wirkung und Behebbarkeit) 4. Ausgewählte(s) Methode/Datenstruktur/Objekt/… analysieren 5. Eine Änderung durchführen 6. Perfomance-Messung durchführen 7. Falls die Änderung nicht den gewollten Effekt erzielte vielleicht einen Schritt zurück 8. Solange noch Verbesserungen möglich sind weiter bei Schritt 4 9. Messung der Gesamtverbesserung 10. Wieder mit Schritt 1 beginnen da sich meist das gesamte Perfomance-Profil geändert hat

5 Bernhard MährJava Performance Tuning5/25 Bottelneck auswählen Programmteil der viel Rechenzeit verwendet Methode mit 1% Rechenzeit -> max. 1% schneller wenn Algorithmus um 100% schneller Methode mit 10% Rechenzeit um 50% schneller -> Gesamtperformance um 5% besser Nur das Tunen was wirklich bremst

6 Bernhard MährJava Performance Tuning6/25 Compiler Optimierungen arr[1]=arr[1]+5; -> arr[1]+=5; y=x/2; -> y=x>>1; z=x*4; -> z=x<<2; T y = new T(5); T x = (T)y; int x = 0; int x = 1; x = 2; int duration = 24*60*60; String s = + 24 + hours + online; Dummy case-Zweige für Switch-Anweisungen

7 Bernhard MährJava Performance Tuning7/25 Inlineing private int m1() { return 5; } private int m2() { return m1(); } public interface A { public static final boolean DEBUG = false; } public class B { public static int foo() { if (A.DEBUG) System.out.println(Check); return 0; } } final, private und static Methoden können eingefügt werden. Geschieht meist nur wenn keine lokalen Variablen verwendet werden Der Compiler aus dem SDK führt Inlining nur bei Konstanten aus Interfaces aus. Die If-Anweisung wird zur Compilezeit komplett entfernt.

8 Bernhard MährJava Performance Tuning8/25 Optimierungen in Standardanweisungen Datentyp int ist schneller als long, byte, short,… Zugriff auf lokale Variablen ist schneller als Zugriff auf static Variablen Zugriff auf einfache Variablen ist schneller als Zugriff auf Arrays oder Objekte Kurzschluß-Auswertung beachten //statt if (n == Integer.MIN_VALUE || n>0){ //lieber if (n>0 || n == Integer.MIN_VALUE){ Native-Methoden verwenden wenn möglich (zB arraycopy() statt Schleife) Zugriff auf eindimensionale Arrays ist schneller wie auf mehrdimensionale

9 Bernhard MährJava Performance Tuning9/25 Canonicalization public interface GENDER { public static final int FEMALE=1; public static final int MALE=2; } if (user.gender==FEMALE) {…} //Inlining durch Complier public class STATUS { public static final String ONLINE=Online; public static final String OFFLINE=Offline; } if (user.state==STATUS.ONLINE) {…} Boolean t1 = new Boolean(true); System.out.println(t1==Boolean.TRUE); //false System.out.println(t1.equals(Boolean.TRUE)); //true Boolean.TRUE;

10 Bernhard MährJava Performance Tuning10/25 Objekte Erzeugung und GC ist aufwendig Möglichst wenige Objekte verwenden TypeCasts sind teuer instanceof abfragen statt Exception von TypeCast abfangen Einfache Datentypen statt Objekten Objekte wiederverwenden -> Objektpool Objekte im voraus erzeugen

11 Bernhard MährJava Performance Tuning11/25 Initialisieren vs Clonen static int[] Ref_a1 = {1,2,3,4,5,6,7,8,9}; static int[][] Ref_a2 = {{1,2},{3,4},{5,6},{7,8}}; int[] a1 = {1,2,3,4,5,6,7,8,9}; //schneller als int[] array1 = (int [])Ref_a1.clone(); int[][] a2 = (int [][])Ref_a2.clone(); //schneller als int[][] a2 = {{1,2},{3,4},{5,6},{7,8}}; Komplizierte Objekte können schneller geklont als initialisiert werden Mittels Factory-Pattern sehr gut implementierbar private static Something MASTER = new Something(); public static Something getNewSomething() { return (Something) MASTER.clone(); }

12 Bernhard MährJava Performance Tuning12/25 Wiederverwenden von Parameter-Objekten public Dimension setSize(Dimension d) { … d.width=5; d.height=10; return d; } Probleme? realSize = O.setSize(wantedSize); wantedSize.height=7; //realSize.height = ? Lösungen: class FixedDimension { final int height; final int width; } Alle Methoden müssen für die Verwendung von FixedDimension geändert werden

13 Bernhard MährJava Performance Tuning13/25 Wiederverwenden von Parameter-Objekten private static final Dimension D = new Dimension(0,0); public Dimension setSize(Dimension d) { Dimension newd = (Dimension)D.clone(); setSize(d, newd); return newd; } public void setSize(Dimension d, Dimension retd) { … retd.width = 5; retd.height = 10; } Verwendung wie bisher, für Performance-Tuning kann die 2te Methode verwendet werden o.setSize(d,d);

14 Bernhard MährJava Performance Tuning14/25 Schleifen for(long i=0; i<collection.size(); i++) { countArr[0]=countArr[0] + 5 * points; } Unnötige Anweisungen aus der Schleife entfernen Methoden-Aufrufe minimieren Array-Zugriffe vermeiden Umgekehrte FOR-Schleife int count=countArr[0]; int addpoints=5*points; for(int i=collection.size(); --i>=0; ){ count+=addpoints; } countArr[0]=count; for(long i=0; i<collection.size()*50000; i++) { countArr[0]=countArr[0] + 5 * points; } Laufzeit 1.3.1 Code / 1.1.8 No JIT: 225,844 s / 1097% Laufzeit 1.3.1 Code / 1.1.8: 2,864 s / 14% Laufzeit 1.4.1 Code / 1.4.1 Client:31,845 s / 155% Laufzeit 1.4.1 Code / 1.4.1 Server:20,580 s / 100% int addpoints = points; for(long i=0; i<collection.size()*50000; i++) { countArr[0]=countArr[0] + 5 * addpoints; } Laufzeit 1.3.1 Code / 1.1.8 No JIT: 228,559 s / 1111% Laufzeit 1.3.1 Code / 1.1.8: 3,305 s / 16% Laufzeit 1.4.1 Code / 1.4.1 Client:36,813 s / 155% Laufzeit 1.4.1 Code / 1.4.1 Server:25,046 s / 122% int addpoints = points; int iter = collection.size()*50000; for(long i=0; i<iter; i++) { countArr[0]=countArr[0] + 5 * addpoints; } Laufzeit 1.3.1 Code / 1.1.8 No JIT: 128,505 s / 624% Laufzeit 1.3.1 Code / 1.1.8: 3,305 s / 16% Laufzeit 1.4.1 Code / 1.4.1 Client:14,591 s / 71% Laufzeit 1.4.1 Code / 1.4.1 Server:4,136 s / 20% int addpoints = points * 5; int iter = collection.size()*50000; for(long i=0; i<iter; i++) { countArr[0]=countArr[0] + addpoints; } Laufzeit 1.3.1 Code / 1.1.8 No JIT: 146,100 s / 710% Laufzeit 1.3.1 Code / 1.1.8: 3,505 s / 17% Laufzeit 1.4.1 Code / 1.4.1 Client:14,331 s / 70% Laufzeit 1.4.1 Code / 1.4.1 Server:4,136 s/ 20% int addpoints = points * 5; int iter = collection.size()*50000; int count = countArr[0]; for(long i=0; i<iter; i++) { count=count + addpoints; } countArr[0] = count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 98,862 s / 480% Laufzeit 1.3.1 Code / 1.1.8: 3,705 s / 18% Laufzeit 1.4.1 Code / 1.4.1 Client:11,897 s / 58% Laufzeit 1.4.1 Code / 1.4.1 Server:4,116 s/ 20% int addpoints = points * 5; int iter = collection.size()*50000; int count = countArr[0]; for(int i=0; i<iter; i++) { count=count + addpoints; } countArr[0] = count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 44,384 s / 216% Laufzeit 1.3.1 Code / 1.1.8: 1,533 s / 7% Laufzeit 1.4.1 Code / 1.4.1 Client:6,900 s / 34% Laufzeit 1.4.1 Code / 1.4.1 Server:0,701 s / 3% int addpoints = points * 5; int iter = collection.size()*50000; int count = countArr[0]; for(int i=0; i<iter; i++) { count+= addpoints; } countArr[0] = count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 44,474 s / 216% Laufzeit 1.3.1 Code / 1.1.8: 1,602 s / 8% Laufzeit 1.4.1 Code / 1.4.1 Client:6,980 s / 34% Laufzeit 1.4.1 Code / 1.4.1 Server:0,701 s / 3% int addpoints = points * 5; int iter = collection.size()*50000; int count = countArr[0]; for(int i=iter; --i>=0;) { count+= addpoints; } countArr[0] = count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 40,769 s / 198% Laufzeit 1.3.1 Code / 1.1.8: 1,602 s / 8% Laufzeit 1.4.1 Code / 1.4.1 Client:6,229 s / 30% Laufzeit 1.4.1 Code / 1.4.1 Server:0,701 s / 3% int addpoints=5*points; int count=countArr[0]; for(int i=collection.size()*50000; --i>=0; ){ count+=addpoints; } countArr[0]=count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 41,610 s / 202% Laufzeit 1.3.1 Code / 1.1.8: 1,513 s / 7% Laufzeit 1.4.1 Code / 1.4.1 Client:7,651 s / 37% Laufzeit 1.4.1 Code / 1.4.1 Server:0,711 s / 3% int count=countArr[0]; int addpoints=5*points; int i=collection.size()*50000; for(; --i>=0; ){ count+=addpoints; } countArr[0]=count; Laufzeit 1.3.1 Code / 1.1.8 No JIT: 39,997 s / 194% Laufzeit 1.3.1 Code / 1.1.8: 1,512 s / 7% Laufzeit 1.4.1 Code / 1.4.1 Client:7,691 s / 37% Laufzeit 1.4.1 Code / 1.4.1 Server:0,711 s / 3%

15 Bernhard MährJava Performance Tuning15/25 Schleifen / Exceptions Exception Terminated Loops try { for(int i=0;;i++) {…} } catch (Exception e) {} Bei vielen Schleifendurchläufen schneller aber nicht sauber Try-Blocks ohne geworfene Exception bremsen aber nicht viel (bis JDK 1.1.8) Try-Blocks mit geworfener Exception sind deutlich langsamer und sollten im normalen Programmablauf nicht vorkommen

16 Bernhard MährJava Performance Tuning16/25 Rekursionen public static long fact_rec (int n) { return n*fact_rec(n-1); } public static long fact_iter (int n) { long result = 1; while (n>1) { result *= n--; } return result; } Iterative Version braucht nur 88% der Zeit Gecachte Zwischenergebnisse: 4%

17 Bernhard MährJava Performance Tuning17/25 Laden beschleunigen Spash-Screen Unkompremierte JAR-Archive Preload von Klassen (Achtung: Caching der VM nicht behindern) Lazy-Initialisation

18 Bernhard MährJava Performance Tuning18/25 String / StringBuffer Insert, Append, Delete ist auf StringBuffer viel schneller als auf Strings Substring auf String kopiert nichts -> schnell toString() auf StringBuffer kopiert nichts -> schnell allerdings wird Größe nicht verkleinert

19 Bernhard MährJava Performance Tuning19/25 Threads/Synchronized Falsch eingesetzte Threads und jedes Synchronized bremst Ein Thread, der die Aufgaben an einen anderen übergibt, und dann auf deren Beendigung wartet ist sinnlos und langsam! Syncronized Methoden sind 10 mal (mit JIT Compilern) bis 100 mal langsamer Synchronisierte Objekte verwenden und bei Performance-Problemen auf die Unsynchronisierten ausweichen.

20 Bernhard MährJava Performance Tuning20/25 Syncronized Wrappers für eigene Klassen public interface Adder { public void add(int aNumber); } public class UnsyncedAdder implements Adder { int total; int numAdditions; public void add(int add){ total+=add; numAdditions++;} } public class SyncedAdder implements Adder { Adder a; public SyncedAdder(Adder a) { this.a = a; } public synchronized void add( int add) { a.add(add); } }

21 Bernhard MährJava Performance Tuning21/25 Collections InterfaceClassSyncEigenschaften MapHashMapNeinSchnellstes Map HashTableJaLangsamer als HashMap aber schneller als sync. HashMap TreeMapNeinLangsamer als HashTable; Geordnete Iteration der Keys möglich SetHashSetNeinSchnellstes Set; Langsamer als HashMap aber Set TreeSetNeinLangsamer als HashSet; Geordnete Iteration der Keys möglich ListArrayListNeinSchnellste Liste VectorJaLangsamer als ArrayList aber schneller als sync ArrayList StackJaGleich schnell wie Vector; LIFO Queue LinkedListNoLangsamer als andere List-Klassen; für Spezial-Fälle schneller

22 Bernhard MährJava Performance Tuning22/25 Selber implementieren? Sind die Implementierungen der Java-Libaries optimal? An den Verwendungszweck angepaßte Implementierung senkt die Ausführungszeit auf bis zu 0.7% Selbstgeschriebene IntArrayList statt der ArrayList verwenden

23 Bernhard MährJava Performance Tuning23/25 Text einlesen (Lange Zeilen) 1.21.2 kein JIT 1.3HotSpot 1.0 HotSpot 2nd Run 1.1.6 Unbuffered Inputstream 1951%3567%1684%1610%1641%1341% Buffered Inputstream 100%450%52%56%45%174% 8K Buffered Inputstream 102%477%50%45%48%225% Buffered Reader 47%409%43%74%41%43% Custom-built Reader 26%351%37%81%36%15% Custom reader and converter 12%69%18%77%17%10%

24 Bernhard MährJava Performance Tuning24/25 Text einlesen (Kurze Zeilen) 1.21.2 kein JIT 1.3HotSpot 1.0 HotSpot 2nd Run 1.1.6 Unbuffered Inputstream 1308%2003%1101%1326%1232%871% Buffered Inputstream 100%363%33%50%54%160% 8K Buffered Inputstream 101%367%31%41%54%231% Buffered Reader 111%554%39%149%45%127% Custom-built Reader 19%237%28%94%26%14% Custom reader and converter 9%56%21%80%53%8%

25 Bernhard MährJava Performance Tuning25/25 Quellen Jack Shirazi: Java Performance Tuning ab Feb 2003 neue stark erweiterte Auflage http://www.javaperformancetuning.com/ http://www- 2.cs.cmu.edu/~jch/java/optimization.html http://www- 2.cs.cmu.edu/~jch/java/optimization.html


Herunterladen ppt "Java Performance Tuning Performance Tuning is similar to playing a strategy game but happily you usually get paid for it."

Ähnliche Präsentationen


Google-Anzeigen