iText Performance Optimierung mit AppDynamics und YourKit
27.11.2010 | 2 Minuten Lesezeit
Wie sinnvoll sich eine Performance Monitoring Lösung mit einem Profiler verbinden lässt, kann man ganz anschaulich an folgendem Beispiel feststellen.
Bei meinem regelmäßigen Rundgang durch das bei uns in der Continuous Integration Umgebung mitlaufende AppDynamics fand ich einen interessanten HotSpot in iText.
Mittels iText , einer früher komplett freien, mittlerweile teilweise kommerziellen Java Bibliothek, kann man sehr leicht PDFs auslesen. Dafür verwendet man einfach einen PDFReader:
1PdfReader reader = new PdfReader(filename);
Wirklich problemlos!
Jedenfalls scheinbar. Den von mir gefundenen Hotspot kann man in folgendem Screenshot aus AppDynamics leicht selbst entdecken:
[singlepic id=336 w=560 float=]
In diesem Fall gehen fast 20% der Gesamtzeit durch das Öffnen von 2 PDFs verloren. Meine Neugierde war geweckt. Was passiert dort?
Der Invocation Trace zeigt, dass im Constructor des PdfReader ein PRTokeniser erstellt wird, der ein RandomAccessFileOrArray erstellt. Dort wird dann entweder ein RandomAccessFile oder ein MappedRandomAccessFile erstellt. Letzteres liest über einen FileChannel die Datei direkt in den Arbeitsspeicher. Wenn das als langsam gefunden wurde, ist das vielleicht gar keine so gute Idee, dachte ich mir und begann meine Suche nach einer Alternative.
Also war ein kleines Microbenchmark für unsere Funktion, welche die in dem PDF enthaltenen Felder ausliest, geschrieben.
Nach 3000 warmup Aufrufe folgten 10000 gemessene Aufrufe und ergaben 12,3 Sekunden auf meiner Maschine (Win 7 32bit, Java 1.6.20, -server).
Um besser zu verstehen was passiert, ließ ich YourKit als Profiler mitlaufen. Dieser berichtete mir am Schluss:
Die gesuchte Alternative zum Ausprobieren fand ich in einem Constructor, der ein RandomAccessFileOrArray entgegen nimmt, so dass ich dort eine andere Implementierung zum Dateiauslesen versuchen kann. Mit möglichst kleinen Schritten wollte ich mich dem Thema nähen und tat das was sonst der Code im „filename-Constructor“ tun würde:
1PdfReader reader = new PdfReader(new RandomAccessFileOrArray(filename), null);
Doch zu meiner Überraschung stellte ich fest, dass nun die 10k Durchläufe weniger als die Hälfte der Zeit benötigten: 5,8 Sekunden. Und das obwohl ich doch nichts Anderes tat als vorher?
Was war da passiert? Nun die Javadoc dieses Konstruktors des PdfReaders sagt es bereits:
1/** 2* Reads and parses a pdf document. Contrary to the other constructors only the xref is read 3* into memory. The reader is said to be working in "partial" mode as only parts of the pdf 4* are read as needed. 5**/
Aha, interessant. Könnte für meinen Anwendungszeck des reinen Felderauslesens sogar erheblich performanter sein.
Bestätigt wird dies durch YourKit. Keine Spur mehr von den teuren Konstruktoren:
Ganz offensichtlich ist diese Variante wesentlich schneller. Zwar war dies nicht die Stelle nach der ich gesucht hatte, jedoch sollte man bei Performance auch gerne mal nach den tiefhängenden Früchten greifen. Zumal die Stelle an der die Korrektur erfolgt, oft nicht genau die im Profiler oder Monitor gesehene Stelle ist.
Seit dieser Optimierung haben wir nie wieder eine langsame Codeausführung in unserem PDFServide entdecken können.
Ich denke dieses Beispiel zeigt ganz anschaulich wie man sinnvoll Performanceoptimierungen durchführen kann:
- Permanente Messung in Produktion und Test.
- Analyse von Ausreißern und Anaomalien.
- Evaluierung alternativer Implementierungen im Bereich der Anomalie mit einem Profiler.
- Wenige einfache Änderungen mit großer Wirkung durchführen.
- Weiter beobachten.
Weitere Beiträge
von Fabian Lange
Dein Job bei codecentric?
Jobs
Agile Developer und Consultant (w/d/m)
Alle Standorte
Weitere Artikel in diesem Themenbereich
Entdecke spannende weiterführende Themen und lass dich von der codecentric Welt inspirieren.
Gemeinsam bessere Projekte umsetzen.
Wir helfen deinem Unternehmen.
Du stehst vor einer großen IT-Herausforderung? Wir sorgen für eine maßgeschneiderte Unterstützung. Informiere dich jetzt.
Hilf uns, noch besser zu werden.
Wir sind immer auf der Suche nach neuen Talenten. Auch für dich ist die passende Stelle dabei.
Blog-Autor*in
Fabian Lange
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.
Du hast noch Fragen zu diesem Thema? Dann sprich mich einfach an.