java performance tuning performance tuning is similar to playing a strategy game but happily you...
Post on 05-Apr-2015
122 Views
Preview:
TRANSCRIPT
Java Performance Tuning
Performance Tuning is similar to playing a strategy game but happily you usually get paid for it.
Bernhard Mähr Java Performance Tuning 2/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
Bernhard Mähr Java Performance Tuning 3/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
Bernhard Mähr Java Performance Tuning 4/25
Schritte
1. Benchmark einbauen und Tests ausführen2. Bottlenecks identifizieren3. 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ühren6. Perfomance-Messung durchführen7. Falls die Änderung nicht den gewollten Effekt
erzielte vielleicht einen Schritt zurück8. Solange noch Verbesserungen möglich sind weiter
bei Schritt 49. Messung der Gesamtverbesserung10. Wieder mit Schritt 1 beginnen da sich meist das
gesamte Perfomance-Profil geändert hat
Bernhard Mähr Java Performance Tuning 5/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
Bernhard Mähr Java Performance Tuning 6/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
Bernhard Mähr Java Performance Tuning 7/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.
Bernhard Mähr Java Performance Tuning 8/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){//lieberif (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
Bernhard Mähr Java Performance Tuning 9/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); //falseSystem.out.println(t1.equals(Boolean.TRUE)); //true
Boolean.TRUE;
Bernhard Mähr Java Performance Tuning 10/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
Bernhard Mähr Java Performance Tuning 11/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();}
Bernhard Mähr Java Performance Tuning 12/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
Bernhard Mähr Java Performance Tuning 13/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);
Bernhard Mähr Java Performance Tuning 14/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%
Bernhard Mähr Java Performance Tuning 15/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
Bernhard Mähr Java Performance Tuning 16/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%
Bernhard Mähr Java Performance Tuning 17/25
Laden beschleunigen
Spash-Screen Unkompremierte JAR-Archive Preload von Klassen (Achtung: Caching der VM nicht
behindern) Lazy-Initialisation
Bernhard Mähr Java Performance Tuning 18/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
Bernhard Mähr Java Performance Tuning 19/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.
Bernhard Mähr Java Performance Tuning 20/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); }}
Bernhard Mähr Java Performance Tuning 21/25
Collections
Interface Class Sync Eigenschaften
Map HashMap Nein Schnellstes Map
HashTable Ja Langsamer als HashMap aber schneller als sync. HashMap
TreeMap Nein Langsamer als HashTable; Geordnete Iteration der Keys möglich
Set HashSet Nein Schnellstes Set; Langsamer als HashMap aber Set
TreeSet Nein Langsamer als HashSet; Geordnete Iteration der Keys möglich
List ArrayList Nein Schnellste Liste
Vector Ja Langsamer als ArrayList aber schneller als sync ArrayList
Stack Ja Gleich schnell wie Vector; LIFO Queue
LinkedList No Langsamer als andere List-Klassen; für Spezial-Fälle schneller
Bernhard Mähr Java Performance Tuning 22/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
Bernhard Mähr Java Performance Tuning 23/25
Text einlesen (Lange Zeilen)
1.2 1.2 keinJIT
1.3 HotSpot1.0
HotSpot2nd 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%
Bernhard Mähr Java Performance Tuning 24/25
Text einlesen (Kurze Zeilen)
1.2 1.2 keinJIT
1.3 HotSpot1.0
HotSpot2nd 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%
Bernhard Mähr Java Performance Tuning 25/25
Quellen
Jack Shirazi: Java Performance Tuningab Feb 2003 neue stark erweiterte Auflage
http://www.javaperformancetuning.com/ http://www-2.cs.cmu.edu/~jch/java/
optimization.html
top related