Azul: Java Performance ExplainedIn diesem Blog habe ich schon über Azul berichtet: Die Firma baut einen Mulitprozessor Server für Java Anwendungen, der verhältnismäßig billig ist, bis zu 384 Prozessoren verträgt und Synchronisierung und Garbage Collection sehr geschickt implementiert, so dass die Performance der Anwendungen sehr positiv beeinflusst wird.
In diesem Vortrag ging es jedoch um ein ganz anderes Thema: Welche falschen Java Performance Tipps gibt es? Dabei kommt es vor allem darauf an, dass man mehrere JVMs vergleicht, den ein Trick, der auf einer JVM etwas bringt, kann auf einer anderen JVM ein Nachteil ergeben.
Die Ergebnisse:
- Exceptions, um eine Schleife zu verlassen, sind teuer. Das ist recht klar, da das Werfen von Exceptions eben teuer ist.
- Klassen oder Methoden final zu machen, bringt praktisch nie einen Vorteil
- try / catch hat meistens keine Kosten
- Es gibt anscheinend Leute, die statt einem virtuellen Methoden Aufruf mit instance_of den Typ des Objekts abfragen oder gar dafür eine Instanzvariable einführen, die je nach Typ des Objekts anders gesetzt ist. Das bringt keinen Vorteil, aber unwartbaren Code...
- Synchronisation kostet 55-110 ns, wenn keine Contention (=paralleler Zugriff) vorkommt. Das ist also nicht so viel.
- Objekt Pooling bringt auch bei großen Objekten nichts. Der einzige gute Grund für Pooling sind also Objekte, die extern Ressourcen allokieren, so dass die Erzeugung wirklich teuer ist
- In Java 5 sind foreach, Autoboxing und varargs tatsächlich nicht nachteilhaft. Bei Enums führt jedoch ein .values() zu einem Clonen des Arrays der Werte, was deutlich suboptimal ist. Allerdings wird hier wahrscheinlich früher oder später ein Fix kommen.
Es gab dann noch den Tipp, dass Garbage Collection von der JVM abhängig ist, so dass Feintuning auf einer anderen Maschinen zu Problemen führen kann. Synchronisierung hingegen wichtig, weil man in Zukunft deutlich mehr Multi CPU Maschinen haben wird, so dass Fehler durch fehlende synchronized zunehmend ein Problem werden.
Zum Abschluss gab es als finalen Tipp, dass JVMs sauberen Code favorisieren: Sie sind eben darauf optimiert, den Stil zu unterstützen, der am häufigsten verwendet wird, damit möglichst viele was davon haben. Und die andere Nachricht ist, dass Optimierungen eben JVM spezifisch sein können, so dass man wegen Portabilität aber auch wegen zukünftigen JVMs vorsichtig sein muss.