Im ersten Teil ging es um die Top 5 Ursachen für Performance-Probleme in Java und J2EE-Umgebungen. Nun will ich mich den anderen Ursachen widmen, die zu Lasten der Performance gehen.
Komplexe In-Memory Sortierung/Listenoperationen
An einigen Stellen eines Software-Systems werden häufig viele Informationen zusammengeführt. Gerade bei der Ermittlung von Informationen aus Listen stecken manchmal die Tücken im Detail. Mit verschiedenen Listen, die unterschiedliche Informationen enthalten sammelt sich schnell die Anzahl der Listen-Iterationen, da sich diese mit zunehmender Verschachtelung potenzieren. Stammen die Informationen aus unterschiedlichen Quellen (Text- oder XML-Dateien, Web-Service, Datenbank, Enterprise Information System), so lässt es sich nicht vermeiden, alle Listen zu verarbeiten. Da bleibt häufig nur die Optimierung in der Datenbeschaffung. Stammen die Daten jedoch aus einer Quelle (aus einer Datenbank), so lässt sich manchmal durch eine geschickte SQL Abfrage einiges an Performance gewinnen.
Mögliche Optimierungen können sein:
- Verlagerung der Sortierung in eine Datenbank
- Anzahl der Listen und Sortierungen verringern
- Vereinfachung der Programmlogik
Falsche Nutzung von Komponenten
Aus fachlichen Anforderungen ergeben sich technische Lösungen. Aus technischen Lösungen und Ideen des Kunden weitere Anforderungen. Entsteht nun eine Anforderung, die auf bestehenden Komponenten aufsetzt, die jedoch nicht so richtig zu den eingesetzten Komponenten passt, so können schnell Bottlenecks entstehen. Soll beispielsweise eine detaillierte Suche um eine Volltextsuche erweitert werden (die Daten aus einer Datenbank abfragt), so wird gerne die bestehende Technik-Basis weitergenutzt. Dabei sind Datenbanken nicht gerade die richtige Wahl wenn es darum geht, einen Volltext-Index aufzubauen. Datenbanken dienen dem Speichern und Abfragen von Daten, der Suche nur sehr begrenzt.
Ein anderes Beispiel ist die Kopplung von unterschiedlichen Systemen. Waren noch vor 10 Jahren CORBA und eine Datenbank-Schnittstelle (System A legt werte in einer Datenbank ab, System B verarbeitet diese, System A holt die verarbeiteten Daten aus der Datenbank) eine gängige Praxis, so erlauben es heute Web-Services, RESTful Interfaces und andere Standard-Komponenten, diese Systeme miteinander zu vernetzen. Grundsätzlich gilt: So wenig (Overhead) wie möglich, so viel (Funktionalität, Sicherheit, usw.) wie nötig. Oftmals reichen wenige Daten und ein einfaches XML-Format aus, um erforderliche Daten zwischen System zu übertragen. Spätestens wenn ein Web-Service-Aufruf 5 MB Nutzdaten überträgt stellt sich die Frage: Setze ich die richtige Komponente für meine Anforderung ein?
Mögliche Optimierungen können sein:
- Fragestellung: Welche Anforderung gilt es abzudecken, was sind die gängigen Lösungswege?
- Einsatz einer Datenbank für Speichern und Abfragen von Daten, Suche begrenzt (Ideale Suche über eindeutige Parameter wie z. B. Foreign Keys)
- Einsatz eines Volltext-Index für Volltext-Suche (enorme Performance-Steigerung)
- Nutzung von gängigen und Ressourcen-schonenden Protokollen, ggfs. Minimierung der Datenvolumen/Strukturen falls möglich