Loading

Softwareperformance verbessern und Programme beschleunigen

Langsame Software und Wartezeiten in Programmabläufen stören Arbeitsprozesse und frustrieren die User. Langes Warten macht Benutzer und Kunden unzufrieden, verlangsamt Prozesse, verringert den Output und verschlechtert die User Experience. Dieser Artikel beinhaltet grundlegende Ideen zur Lösung der wichtigsten Performanceprobleme in Softwareprojekten mit Fokus auf Unternehmenssoftware.

Schlechte Softwareperformance trotz brandneuer Hardware

Computer und Server haben heute viel mehr Leistung als noch vor 10 Jahren. Programme können mehrere CPU Cores gleichzeitig nutzen und verfügen über mehr Arbeitsspeicher als je zuvor. Zusätzlich sorgen Solid-State-Drives (SSD) für blitzschnelle Festplattenzugriffe und höchste Datentransferraten von der Disk ins Memory und ins Programm. Standardmässiges Gigabit Ethernet an jedem Arbeitsplatz bringt schliesslich die verarbeiteten Daten im Bruchteil einer Sekunde vom Server zum Enduser.

Software beschleunigen

Trotz der massiven Beschleunigung durch neue Hardware sind langsame Programme in vielen Unternehmen heute immer noch keine Seltenheit. Betroffen sind insbesondere Programme, die über Jahre hinweg gewachsen sind und bei welchen immer wieder neue Features hinzugefügt wurden. Spannender Weise können genau diese Programme in vielen Fällen nur marginal von der neuen Hardware profitieren.

Folgend möchte ich aufzeigen, was die Hauptgründe für schlechte Performance sind und mit welchen Mitteln sich die Softwareperformance verbessern lässt.

5 Hauptgründe für schlechte Softwareperformance

Wir beginnen mit einer Aufzählung der fünf Hauptgründe für schlechte Softwareperformance, die ich in den letzten Jahren selber in den verschiedensten Software Projekten gesehen und optimiert habe. Die Reihenfolge ist mehr oder weniger willkürlich. Der Impact der verschiedenen Ursachen ist unterschiedlich und kann von Projekt zu Projekt variieren.

Generell gibt es nur zwei grundlegende Massnahmen und die Softwareperformance zu verbessern:

  1. Programm für bessere Performance optimieren
  2. Hardware skalieren und parallelisieren

Wichtig ist, dass skalieren und parallelisieren nur funktioniert, wenn die Software bereits für Performance ausgelegt ist. Zum Beispiel kann ein Programm, dass immer nur einen einzigen Prozessorkern nutzt nicht von einer neuen CPU mit mehr Cores profitieren. Auch wird die Performance nur sehr wenig verbessert, wenn eine solche Software auf mehrere Server verteilt wird. Aus diesem Grund ist es wichtig, dass die Software zuerst optimiert wird, bevor über die Skalierung der Hardware nachgedacht wird.

4 Vorgehensschritte zur Optimierung der Softwareperformance

Software Probleme werden generell in 4 grundlegenden Schritten gelöst. Für die Softwareperformance bedeutet dies konkret:

  1. Identifizieren
  2. Profilieren
  3. Optimieren
  4. Testen

Im ersten Schritt muss die langsame, zu optimierende Prozedur identifiziert werden. Zum Beispiel klickt ein User auf einen Button, der einen Report erzeugen soll. Auf den Click folgt eine lange Wartezeit von mehreren Sekunden, im schlimmsten Fall vielleicht sogar Minuten. Der Click ist das auslösende Event, dessen Code folglich Schritt für Schritt optimiert werden muss.

Nach der Identifizierung eines spezifischen Performanceproblems, wird die dazugehörige Prozedur im Quelltext des Programmes gesucht und anschliessend profiliert. Die Profilierung kann mit Hilfe eines Software Analyse Tools oder mit Zeitstempeln einem einfachen Logfile durchgeführt werden.

Mit Hilfe der Daten aus der Profilierung werden die richtigen Mittel zur Performanceoptimierung ausgewählt und an den problematischen Stellen in den Quelltext eingebaut oder auf der Datenbank umgesetzt. Im schlimmsten Fall müssen ganze Codeteile umgebaut werden. Werden grosse Programmteile umprogrammiert, spricht man von Refactoring. Generell wird in den meisten Fällen versucht grosses Refactoring des Quelltextes zu verhindern. Einerseits um Aufwand und Kosten zu sparen, andererseits führt Refactoring häufig zu Bugs und Softwareinstabilitäten.

Ist eine Software generell zu langsam, können bereits kleine, gezielte Änderungen an der Datenbank Wunder wirken.

Alle Änderungen müssen natürlich mit den üblichen Mitteln ausgiebig getestet werden, so dass die Qualität der Software gewährleistet bleibt.

Typische Mittel zur Optimierung der Softwareperformance

Im Folgenden werden die wichtigsten Massnahmen zur Optimierung der Softwareperformance beschrieben.

Datenbank Tuning, Query Optimierung und Indexierung

Speichert das Programm Daten in einer relationalen Datenbank, ist diese häufig die Hauptursache für eine schlechte Performance. Generell nutzen Datenbanken sehr schnelle Datenstrukturen zum Speichern und Lesen der Programmdaten. Eine schlechte Datenstruktur und fehlerhafte Queries können aber dazu führen, dass Abfragen auf einer Datenbank trotzdem sehr langsam sind.

Langsame Queries lassen sich durch reorganisieren der Abfrage oder durch den gezielten Einsatz von Indexes beschleunigen. Arbeitet die Datenbank mit sehr vielen verschiedenen Tabellen auf welchen aggregierte Abfragen ausgeführt werden, kann es nötig sein, eine aggregierte, materialisierte View zu erstellen. Die meisten modernen DBMS unterstützen materialisierte Views.

Eine gezielte Indexierung hilft langsame Abfragen über grosse Datenmengen zu beschleunigen. Ein Index über die richtigen Spalten kann zu massiven Performancegewinnen führen. Indexe sollten aber nie auf Vorrat gesetzt werden, da unnötiges Indexing die Insert und Update Performance negativ beeinflusst. Ungezieltes Indexieren, auch Overindexing genannt, verlangsamt Programme anstatt sie zu beschleunigen. Indexe sollten aus diesem Grund nur spezifisch gesetzt werden und nur für eine ganz gezielte Queryoptimierung.

Volltext-Indexe werden immer dann genutzt, wenn Abfragen über Textfelder auf das Vorkommen bestimmter Wörter oder Wortkombinationen ausgeführt werden müssen. Auch hier sind gewaltige Performancegewinne möglich.

Auch kann die Konfiguration des Datenbank Servers eine wichtige Rolle bei der Geschwindigkeit einzelner Queries spielen. Generell sollte ein Datenbankserver über viel Memory, CPU-Power und sehr schnelle Disks verfügen. Ob und welche Konfigurationsparameter des Datenbankservers angepasst werden, muss von Fall zu Fall analysiert werden und hängt massgebend von den gespeicherten Daten ab.

Multi-threading und Multi-processing

Um die Leistung moderner CPUs nutzen zu können, müssen Programme mehrere Prozesse oder noch besser mehrere Threads nutzen. Man spricht von Multi-Processing und Multi-threading. Multi-Threading unterschiedet sich von Multi-Processing dadurch, dass bei Multi-Threading das gleiche Programm im Memory mehrfach ausgeführt wird. Bei Multi-Processing werden mehrere, eigene Prozessinstanzen ausgeführt.

Wird ein Programm ohne Framework und ohne explizites Multi-Threading entwickelt nutzt es standardmässig immer nur einen einzigen Prozessorkern.

Nutzt ein Programm über längere Zeit 100% eines einzigen CPU Cores, kann Multi-Threading die Performance verbessern. Ein Single-Threaded Programm Multi-Threaded zu machen ist aber mit zahlreichen Schwierigkeiten verbunden. Multi-Threading und die daraus resultierenden Race-Conditions sind häufig Ursache für Programm Instabilitäten und flaky Tests.

Einfacher kann es sein, einzelne Programmteile in separate Prozesse auszulagern und mittels Interprozesskommunikation (IPC) anzubinden. Durch das Aufteilen auf mehrere, getrennte Teilprozesse, kann Performance gewonnen werden, ohne dass der Code komplett umgebaut werden muss. Zudem hat Multi-Processing den Vorteil, dass jeder Teilprozess Single-Threaded läuft und dadurch keine Race-Conditions auftreten können.

Object und Page Caching

Ist insbesondere die Lesezeit Ihrer Daten aus der Datenbank oder von der Disk die Ursache eines Performanceproblems, so lässt sich dies in vielen Fällen durch Object-Caching lösen. Anstatt die Daten bei jedem Zugriff aus der Datenbank zu laden, werden die Daten bei einem Caching-Server hinterlegt.

Vor allem bei Webapplikationen und Apps mit REST Backend liefern Redis und Memcached sehr gute Ergebnisse. Das Datenobjekt wird einmal aus der Datenbank geladen und anschliessend beim Caching Server hinterlegt. Folgezugriffe auf das gleiche Objekt laufen über den Cache, welcher sich im Memory des Servers befindet. Prinzipiell lassen sich auf eine ähnliche Art und Weise mit Hilfe von Varnish ganze Webseiten im Memory speichern. Dies beschleunigt nicht nur die Webapplikation sondern trägt massgebend dazu bei die Serverlast zu reduzieren.

Load-Balancing und Sharding

Die Verteilung der Last auf mehrere Server, so genanntes Load-Balancing ist eines der einfachsten Mittel, die Serverlast zu senken und damit die Applikationsperformance zu steigern.

Bei Sharding handelt es sich um einen Load-Balancing Mechanismus für grosse relationale Datenbanken. Dabei werden grosse Datenmengen anhand eines Schlüssels partitioniert und mehrere so genannter Shards aufgeteilt. Die einzelnen Shards werden den von verschiedenen Datenbank Servern zur Verfügung gestellt. Dadurch kann auf relationalen Datenbanken ein einheitliches Load-Balancing erzielt werden.

Load-Balancing und Sharding sind Skalierungsmassnahmen. Sie lassen sich nur dann zielführend einsetzen, wenn die bestehende Hardware bereits optimal ausgelastet wird. Langsame oder fehlerhafte Abfragen werden dadurch nur marginal schneller.

Gute Performance ist heute für jedes Programm ein Muss

Benutzer wollen keine langsamen Programme bedienen und sich vor dem Computer langweilen. Darum Softwareperformance ist ein zentrales Element für eine hohe User Experience und zufriedene Benutzer. Wird Software für zahlreiche Kunden entwickelt, ist Performance ein Schlüsselelement um sich von der Konkurrenz anzuheben. Ist die Performance schlecht, wechselt der User zur Konkurrenz.

Wir machen Ihrer Applikation Beine

Unsere Spezialisten unterstützen Sie gerne bei der Analyse, bei der Profilierung und bei der Optimierung bestehender Programme und Datenbanken. Nachdem wir Ihren Code profiliert haben, machen wir gezielte Vorschläge zur effizienten Verbesserung der Programmperformance. Bei allen Verbesserungen liegt der Fokus stets auf Aufwand und Nutzen. Durch den Einsatz externer Softwarespezialisten, sparen Sie Zeit und Kosten und Ihr Software Team kann sich weiter auf die Weiterentwicklung Ihrer Software konzentrieren.