Veröffentlichen auch Sie Ihre Arbeiten - es ist ganz einfach!
Mehr InfosDiplomarbeit, 2003, 67 Seiten
Diplomarbeit
Private FernFachhochschule Darmstadt; Standort Pfungstadt (Informatik)
1,5
1 Einleitung
2 Theoretische Grundlagen
2.1 Entwicklungsphasen eines Software-Projektes
2.1.1 Die Planungsphase
2.1.2 Die Definitionsphase
2.1.3 Die Entwurfsphase
2.1.4 Die Implementierungsphase
2.1.5 Die Abnahme- und Einführungsphase
2.1.6 Die Wartungs- und Pflegephase
2.2 Software-Teststrategien
2.2.1 Dynamische Tests
2.2.1.1 Diversifizierende Tests
2.2.1.2 Systemtests
2.2.2 Statische Tests
2.3 Analyse von Algorithmen
2.3.1 Empirische Methode zur Analyse von Algorithmen
2.3.2 Mathematische Methode zur Analyse von Algorithmen
2.4 Bausteinbasierte Software-Entwicklung
3 „Leistungsoptimierung im Nachhinein“
3.1 Notwendigkeit einer Leistungsoptimierung
3.2 Gründe für eine „Leistungsoptimierung im Nachhinein“
3.2.1 Abschätzungsrisiken vermeiden
3.2.2 Rechengeschwindigkeit der Hardware nutzen
3.3 Verbesserung der „Leistungsoptimierung im Nachhinein“
4 Prozess zur „Leistungsoptimierung im Nachhinein“
4.1 Planungsphase
4.1.1 Funktionsanalyse durchführen
4.1.2 Leistungsziel festlegen
4.1.3 Lastenheft erstellen
4.1.4 Entwicklungsaufwand abschätzen
4.2 Definitionsphase
4.2.1 Produktumgebung festlegen
4.2.2 Anforderungen spezifizieren
4.2.3 Pflichtenheft erstellen
4.3 Vorbereitungsphase
4.3.1 Quellcode ermitteln
4.3.2 Testumgebung festlegen
4.3.3 Testdaten generieren
4.3.4 Regressionstest durchführen
4.3.5 Zeitmessmethode festlegen
4.3.6 Benchmark-Messung durchführen
4.4 Optimierungsphase
4.4.1 Performance-Analyse durchführen
4.4.1.1 Die Methode „Inspektion“
4.4.1.2 Die Methode „Mathematische Analyse“
4.4.1.3 Die Methode „Performance-Messung“
4.4.2 Optimierungen implementieren
4.4.3 Regressionstest durchführen
4.4.4 Ergebnisse vergleichen
4.4.5 Fehler korrigieren
4.4.6 Benchmark-Messung durchführen
4.4.7 Messergebnisse vergleichen
4.4.8 Abbruchkriterium prüfen
4.5 Abschlussphase
4.5.1 Hilfsfunktionen entfernen
4.5.2 Systemtest durchführen
4.5.3 Produkt freigeben
5 Konzept zur „Leistungsoptimierung im Nachhinein“
5.1 Grundidee
5.2 Grundprinzip eines Optimierungskataloges
6 Entwicklung eines Optimierungskataloges
6.1 Anforderungen an einen Optimierungskatalog
6.1.1 Geeignete Darstellungsform
6.1.2 Thematische Gliederung
6.1.3 Einheitliche Namenskonvention
6.1.4 Ausführliche Dokumentation
6.1.5 Versionisierung der Optimierungsbausteine
6.1.6 Erweiterbarkeit
6.2 Realisierung eines Optimierungskataloges
6.2.1 Produktbeschreibung
6.2.2 Dateiformate
6.2.3 Namenskonventionen
6.2.4 Optimierungsbausteine
6.2.5 Aufbau des Optimierungskataloges
7 Fallbeispiel: Einsatz des Optimierungskataloges
7.1 Aufgabenstellung
7.2 Projektdurchführung
8 Resümee
8.1 Rückblick
8.2 Ergebnisse
8.3 Konsequenzen
8.4 Ausblicke
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 1: Übersicht von Systemtestmethoden
Tabelle 2: Mögliche Komplexitäten von Algorithmen
Tabelle 3: Prozess der „Leistungsoptimierung im Nachhinein“
Tabelle 4: Gliederungsschema für das Lastenheft
Tabelle 5: Einflussfaktoren bei der Aufwandsabschätzung
Tabelle 6: Angaben zur Produktumgebung
Tabelle 7: Methoden zur Quellcode-Ermittlung
Tabelle 8: Verwendete Dateiformate im Optimierungskatalog
Tabelle 9: Optimierungsbausteine vom Typ „Formular“
Tabelle 10: Optimierungsbausteine vom Typ „C++-Klasse“
Tabelle 11: Optimierungsbausteine vom Typ „Programm“
Tabelle 12: Einsatz des Optimierungskataloges in der Planungsphase
Tabelle 13: Einsatz des Optimierungskataloges in der Definitionsphase
Tabelle 14: Einsatz des Optimierungskataloges in der Vorbereitungsphase
Tabelle 15: Einsatz des Optimierungskataloges in der Optimierungsphase
Tabelle 16: Einsatz des Optimierungskataloges in der Abschlussphase
Abbildungsverzeichnis
Abbildung 1: Schichtenmodell zur Programmerarbeitung
Abbildung 2: Änderungskosten mit Verlauf des Projektfortschritts
Abbildung 3: Der Software-Optimierungsprozess
Abbildung 4: Prozess zur „Leistungsoptimierung im Nachhinein“
Abbildung 5: Abläufe in der Planungsphase
Abbildung 6: Abläufe in der Definitionsphase
Abbildung 7: Abläufe in der Vorbereitungsphase
Abbildung 8: Abläufe in der Optimierungsphase
Abbildung 9: Abläufe in der Abschlussphase
Abbildung 10: Struktur des Optimierungskataloges
Abbildung 12: Optimierungsbaustein vom Typ „C++-Klasse“ (Header)
Abbildung 13: Optimierungsbaustein vom Typ „C++-Klasse“ (Teil 1)
Abbildung 14: Optimierungsbaustein vom Typ „C++-Klasse“ (Teil 2)
Im Rahmen dieser Diplomarbeit soll untersucht werden, wie der Entwicklungsaufwand für eine nachträgliche Leistungsoptimierung von bereits bestehenden C++-Programmen reduziert werden kann. Mit dem zu entwickelnden Konzept soll sowohl die Effizienz als auch die Wirtschaftlichkeit der Software-Entwicklung im Unternehmen verbessert werden.
Dies soll am Beispiel von Programmen der Firma 3D-SHAPE GmbH in Erlangen untersucht werden. Die Firma entwickelt und vermarktet optische Sensoren für berührungslose, 3-dimensionale Formvermessung und Software zur Verarbeitung, Analyse und Bearbeitung der 3-dimensionalen Messdaten.
Um die großen Mengen an Messdaten in akzeptabler Zeit zu verarbeiten, sind hoch optimierte Software-Algorithmen erforderlich.
Die Untersuchungen zur nachträglichen Software-Optimierung sind notwendig, da in vielen Software-Projekten ein Trend zur „Leistungsoptimierung im Nachhinein“ zu beobachten ist. Die dabei entstehenden Entwicklungskosten sind hier jedoch wesentlich höher als wenn dieser Aspekt bereits in der Anfangsphase der Entwicklung eines Software-Produktes behandelt worden wäre.
Oft stehen jedoch die vollständige Erfüllung der funktionalen und qualitativen Anforderung sowie die termingerechte Auslieferung der Software im Vordergrund. Erst dann, wenn die Rechner-Hardware die Leistungsanforderungen der Software nicht erfüllen kann, werden in der Wartungs- und Pflegephase des Software-Entwicklungsprozesses eventuell vorhandene Leistungsdefizite durch Maßnahmen zur Leistungsoptimierung beseitigt. Auf diese Weise erhofft man sich im Allgemeinen das Risiko einer Terminüberschreitung zu reduzieren und unnötigen Optimierungsaufwand einzusparen.
Obwohl das Thema durch den sich abzeichnenden Trend aktuell ist, ist mir keine Literaturstelle bekannt, die ein Konzept anbietet, um den Aufwand einer Leistungsoptimierung in der Wartungs- und Pflegephase eines Software-Projektes zu reduzieren.
Das in dieser Diplomarbeit zu entwickelnde Konzept zur Leistungsoptimierung soll diese Lücke - zumindest teilweise - schließen und dem Software-Entwickler helfen, diese Aufgabe möglichst effizient durchzuführen.
Im Rahmen dieser Arbeit werden daher folgende Tätigkeiten durchgeführt:
- Analysieren jener Prozesse, die im Rahmen eines Entwicklungsprojektes für die nachträgliche Optimierung eines Software-Produktes anfallen.
- Entwerfen eines Konzeptes, um mit Hilfe eines Optimierungskataloges[1] den Aufwand für die „Leistungsoptimierung im Nachhinein“ zu reduzieren.
- Erstellen eines erweiterbaren Optimierungskataloges, der in der Basisversion[2] allgemeine Optimierungsbausteine[3] enthält, die dem Entwickler bei der Durchführung einer Optimierungsaufgabe behilflich sind.
- Anhand einer konkreten Aufgabenstellung zeigen, wie das Konzept zur „Leistungsoptimierung im Nachhinein“ mit Hilfe des Optimierungskataloges in der Praxis umgesetzt wird.
Aufgrund der umfangreichen Thematik sowie einer konkreten Aufgabenstellung bei der 3D-Shape GmbH in Erlangen, beschränken sich die Untersuchungen rein auf die nachträgliche Leistungsoptimierung von C++-Programmen, die unter einem Windows-Betriebssystem von Microsoft® auf Rechnern mit Prozessoren der Firma Intel® laufen. Das Konzept ist jedoch ohne Probleme auch auf andere Programmiersprachen und Plattformen übertragbar.
In diesem Kapitel werden die theoretischen Grundlagen erläutert, auf denen sich die Inhalte der nachfolgenden Kapitel beziehen. Aufgrund der einschränkenden Vorgaben bezüglich des Umfangs der Diplomarbeit wird jedoch nur soweit auf die Theorie eingegangen, wie es für das Verständnis der behandelten Thematik unbedingt notwendig ist. Für eine ausführlichere Darstellung der Theorie wird jeweils auf entsprechende Literatur verwiesen.
Wie in der Einleitung bereits erwähnt, findet eine „Leistungsoptimierung im Nachhinein“ meist in der Wartungs- und Pflegephase eines Software-Projektes statt. Zum besseren Verständnis werden in Kapitel 2.1 die Entwicklungsphasen eines Software-Projektes vorgestellt.
Ein wichtiges Thema bei der Leistungsoptimierung besteht im Testen der Software, bei dem durch Benchmark-Tests[4] der Projektfortschritt und durch Regressions- und Systemtests die Produktqualität gemessen werden. In Kapitel 2.2 werden grundlegende Software-Teststrategien erläutert, die für das Verständnis notwendig sind.
Zur effizienten Leistungsverbesserung eines Software-Programmes muss der Quellcode bezüglich Laufzeitverhalten und Speicherbedarf eingehend analysiert werden. In Kapitel 2.3 werden die wichtigsten Methoden zur Analyse von Algorithmen vorgestellt.
Das Konzept zur Leistungsoptimierung setzt auf die Ideen der bausteinbasierten Software-Entwicklung[5] auf. In Kapitel 2.4 werden diese Prinzipien kurz erläutert.
Alle Aktivitäten, die nötig sind, um ein Software-Produkt zu entwickeln, werden in Phasen unterteilt [Bal01, S.55]. In der Literatur findet man unterschiedliche Ansätze für Entwicklungsphasen. Bei [Kro97, S.28ff] gibt es sechs Phasen, während [Rich03, S.71ff] einen moderneren Ansatz vorstellt und sich dabei lediglich auf drei Phasen bezieht. Das nachfolgend beschriebene Phasenmodell von [Bal01, S.51ff] wird jedoch in der Praxis in dieser oder ähnlicher Form häufig eingesetzt.
Bevor mit der eigentlichen Entwicklung eines Software-Produktes begonnen werden kann, muss durch eine Voruntersuchung oder Durchführbarkeitsuntersuchung die fachliche, ökonomische und personelle Durchführbarkeit aufgezeigt werden. Am Ende der Planungsphase steht die Entscheidung über die weitere Vorgehensweise: Weitermachen oder beenden [Bal01, S.58].
Das fachliche Ergebnisdokument der Planungsphase wird oft als Lastenheft oder grobes Pflichtenheft bezeichnet, ergänzt um ein Glossar. Das Lastenheft enthält eine Zusammenfassung aller fachlichen Basisanforderungen, die das zu entwickelnde Software-Produkt aus der Sicht des Auftraggebers erfüllen muss. „Basisanforderungen“ bedeutet eine bewusste Konzentration auf die fundamentalen Eigenschaften eines Produktes und ihre Beschreibung auf einem ausreichend hohen Abstraktionsniveau, das die Anforderungen präzise beschreibt, ohne sich in Details zu verlieren [Bal01, S.63].
Im Glossar sind alle wichtigen Begriffe zu definieren, die zur Beschreibung des Produkts benötigt werden [Bal01, S.65].
Auch bei der „Leistungsoptimierung im Nachhinein“ wird zu Beginn eines Projektes in der Planungsphase ein Lastenheft erstellt, in dem die Anforderungen und Ziele des Projektes beschrieben sind.
Soll ein neues Software-Produkt erstellt werden, müssen die Anforderungen („requirements“) an dieses Produkt in der Definitionsphase von den Anwendungsspezialisten und Systemanalytikern in Zusammenarbeit mit dem Auftraggeber und den potentiellen Benutzern oder Benutzerrepräsentanten in Form einer Produktdefinition beschrieben werden [Bal01, S.118].
Eine Produktdefinition besteht meist aus mehreren Dokumenten. Ein Dokument davon ist meist ein verbal beschriebenes Pflichtenheft. Dieses enthält eine Zusammenfassung aller fachlichen Anforderungen, die das zu entwickelnde Software-Produkt aus der Sicht des Auftraggebers erfüllen muss. Insbesondere werden alle nicht formalisierbaren Anforderungen aufgeführt. Außerdem werden Entwicklungsprioritäten aus Auftraggebersicht festgelegt [Bal01, S.118f].
Bei der „Leistungsoptimierung im Nachhinein“ wird in der Definitionsphase die Produktumgebung festgelegt. Anschließend werden Anforderungen und Ziele genauer definiert und die Resultate in einem Pflichtenheft festgehalten.
Ziel des Entwurfs ist es, ausgehend von der Produktdefinition, einen Produktentwurf zu erstellen, der die Software-Architektur beschreibt und die Spezifikationen der Systemkomponenten enthält [Bal01, S.716].
Bevor mit dem eigentlichen Entwurf begonnen werden kann, müssen die Einsatzbedingungen des Produkts, die Umgebungs- und Randbedingungen geklärt und festgelegt werden [Bal01, S.716].
Bei der „Leistungsoptimierung im Nachhinein“ entfällt diese Phase, da sich hierbei die Software-Architektur im Allgemeinen nicht verändert. Statt dessen werden in einer Vorbereitungsphase Maßnahmen zur Unterstützung einer Optimierungsphase durchgeführt.
Ziel der Implementierung ist es, die in der Entwurfsphase spezifizierten Systemkomponenten durch Programme zu realisieren [Bal01, S.1080f].
Bei der „Leistungsoptimierung im Nachhinein“ wird diese Phase als Optimierungsphase bezeichnet. Hier werden neben der Performance-Analyse und dem Benchmarking[6] weitere Aufgaben wie z.B. das Anpassen vorhandener Software-Komponenten durchgeführt.
Eine Software-Entwicklung endet mit der Abnahme und Einführung des Produkts. Der Auftraggeber (extern oder intern) testet in der Abnahmephase das fertig gestellte Produkt gegen die in der Produktdefinition festgelegten Anforderungen. Nach erfolgter Abnahme wird in der Einführungsphase das Produkt beim externen Auftraggeber (Individual-Software) oder bei Pilotkunden (Standard-Software) installiert und in Betrieb genommen. Die Inbetriebnahme kann durch direkte Umstellung, einen Parallellauf oder einen Versuchslauf erfolgen [Bal01, S.1087]. Mit der erfolgreichen Einführung und der offiziellen Freigabe des Produkts ist die Produktentwicklung beendet [Bal01, S.1089].
Auch bei einem Projekt zur „Leistungsoptimierung im Nachhinein“ gibt es eine ähnliche Entwicklungsphase, die hier jedoch als Abschlussphase bezeichnet wird.
Mit dem Betriebsbeginn eines Produktes beginnt seine Wartung und Pflege. Bei der Wartung wird ein Produkt durch Fehlerkorrekturen stabilisiert und durch Leistungsverbesserungen optimiert. Bei der Pflege wird ein Produkt durch Änderungen an die geänderte Umwelt angepasst und durch funktionale Ergänzungen erweitert. Betrachtet man den Lebenszyklus (life cycle) eines Software-Produktes, dann betragen die Entwicklungskosten zwischen 20% und 33% und die Wartungs- und Pflegekosten zwischen 67% und 80% der gesamten Lebenszykluskosten. Siehe hierzu auch [Bal01, S.1099].
Um den Wartungs- und Pflegeaufwand zu reduzieren schlägt [Bal01, S.1094] eine Verbesserung des Software-Entwicklungsprozesses und eine Verbesserung der Produktivität bei der Wartung und Pflege vor.
Diesen Vorschlag nimmt sich diese Diplomarbeit an, indem versucht wird, durch das Erstellen eines Konzeptes den Wartungsaufwand für eine Leistungsverbesserung zu reduzieren.
Ganz allgemein lassen sich Tests in Blackbox-Tests und Whitebox-Tests klassifizieren. Blackbox-Tests finden aus der Sicht des Anwenders statt. Dabei handelt es sich um Funktionstests[7], da nur interessiert, ob die Funktion ordnungsgemäß erfüllt wird [Alp94, S.40]. Whitebox-Tests finden auf der Ebene des Software-Entwicklers statt. Dieses Testverfahren wird auch als strukturiertes Testen bezeichnet, da Testfälle aufgrund bekannter Strukturen ermittelt werden [Alp94, S.40].
Des Weiteren lassen sich Tests auch in dynamische und statische Tests unterteilen. Siehe dazu [Ligg02, S.35ff] und [Alp94, S.39].
Nach [Ligg02, S.36] werden dynamische Tests (Blackbox-Tests) durch folgende Merkmale repräsentiert:
- Die übersetzte, ausführbare Software wird mit konkreten Eingabedaten versehen und ausgeführt.
- Es kann in der realen Betriebsumgebung getestet werden.
- Dynamische Tests sind Stichprobenverfahren.
Eine Aussage über die korrekte oder unkorrekte Funktion der Software ist im Grunde ausschließlich für die gewählten Testdaten sicher möglich. Das Ziel der dynamischen Tests ist die Erzeugung von Testfällen, die repräsentativ, fehlersensitiv, redundanzarm und ökonomisch sind [Ligg02, S.36].
Eine spezielle Form der dynamischen Tests sind die Benchmark-Tests. Darunter versteht man im Allgemeinen einen Testprozess zur Durchführung einer Leistungsbewertung. Um aussagefähige Testergebnisse zu erhalten, ist es jedoch wichtig, dass solche Tests unter exakt definierten Testbedingungen und mit identischen Testdaten stattfinden.
Im Rahmen der „Leistungsoptimierung im Nachhinein“ werden solche Benchmark-Tests durchgeführt, um die Leistungsfähigkeit eines zu optimierenden Software-Programmes zu bestimmen und durch Leistungsvergleich den Projektfortschritt zu messen.
Die diversifizierenden Tests sind eine Untergruppe der dynamischen Tests. Sie bewerten die Korrektheit der Testergebnisse durch Vergleich der Ergebnisse mehrerer Software-Testversionen. Vorteil der diversifizierenden Tests ist die Möglichkeit zur automatisierten Bewertung der Korrektheit der Testergebnisse [Ligg02, S.39].
Eine Form dieser Techniken sind die Regressionstests. Ein Regressionstest besteht aus der Wiederholung von bereits durchgeführten Testläufen. Die zu testende Software ist pro durchzuführenden Testfall in den gleichen Zustand zu versetzen, wie bei der vorhergehenden Durchführung des Testfalls. Es sind
identische Eingabedaten zu verwenden und die neu erzeugten Ausgaben sind mit den Ausgaben der Vorläuferversion zu vergleichen. Falls keine Unterschiede auftauchen, ist der Regressionstestfall als erfolgreich absolviert anzusehen.
Falls Unterschiede erkannt werden, ist zu prüfen, ob diese gewünscht sind oder ob diese fehlerhafterweise aufgetreten sind. Im erstgenannten Fall ist das geänderte Verhalten für zukünftige Regressionstests als Soll-Verhalten, also als Referenzfall, zu definieren. Im zweiten Fall muss der Fehler lokalisiert und korrigiert werden [Ligg02, S.187].
Bei der „Leistungsoptimierung im Nachhinein“ werden Regressionstests dazu verwendet, um zu kontrollieren, ob die Ergebnisdaten der optimierten Version eines Software-Produktes noch identisch zu den Ergebnisdaten der nicht optimierten Version sind.
Die Systemtests bilden die abschließenden Tests der Software-Entwickler und Qualitätssicherer in der realen Umgebung (System-Software, Hardware, Bedienungsumfeld, technische Anlage) [Bal98, S.537].
In Abhängigkeit von den gewählten Prüfzielen sind unterschiedliche Systemtests auszuführen. Die wichtigsten werden in der folgenden Tabelle kurz vorgestellt. Siehe hierzu auch [Bal98, S.537].
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 1: Übersicht von Systemtestmethoden
Solche Systemtests kommen auch am Ende eines Projektes zur „Leistungsoptimierung im Nachhinein“ zum Einsatz, um die Software-Qualität zu gewährleisten.
In [Alp94, S.39] versteht man statische Tests als Testmethoden, die sich mit den „system requirements“, dem Design und zum Teil auch mit dem Code beschäftigen. Nach [Ligg02, S.40] besitzen alle statischen Tests folgende Merkmale:
- Es erfolgt keine Ausführung der zu testenden Software.
- Die Durchführung ist prinzipiell ohne Computerunterstützung möglich.
- Es werden keine Testfälle gewählt.
- Vollständige Aussagen über die Korrektheit oder Zuverlässigkeit können nicht erzeugt werden.
Statische Tests kann man mit Hilfe der folgenden Methoden durchführen:
- Inspektion [Bal98, S.305],
- Review [Bal98, S.317],
- Walkthrough [Alp94, S.43], [Bal98, S.321].
Im Allgemeinen handelt es sich dabei um Prüfmethoden, bei denen in Team-sitzungen Defekte und Probleme in einem schriftlichen Prüfobjekt identifiziert werden. Eine ausführliche Darstellung dieser Methoden findet man bei [Bal98, S.324].
Bei der „Leistungsoptimierung im Nachhinein“ wird diese Testmethode dazu verwendet, um einen Quellcode durch eine Code-Inspektion auf uneffiziente und unnötige Algorithmen hin zu untersuchen.
Eine der Hauptaufgaben bei der „Leistungsoptimierung im Nachhinein“ ist das Analysieren der Leistungsfähigkeit von Algorithmen. In der Praxis sind vor allem Aussagen betreffend des Zeitverhaltens (die Performance) und dem Speicherplatzbedarf von wesentlicher Bedeutung [BlSchi96, S.96].
In [Sed02, S.50] wird dabei zwischen der empirischen Methode und der mathematischen Methode unterschieden.
[Sed02, S.51] beschreibt die empirische Methode folgendermaßen: „Hat man zwei Algorithmen, die das gleiche Problem lösen, gibt es am Verfahren nichts Geheimnisvolles: Wir führen sie beide aus und stellen fest, welcher Algorithmus länger braucht“.
Folgende Probleme sind dabei nach [Sed02, S.51f] zu lösen:
- Für die Analyse muss eine korrekte und vollständige Implementierung entwickelt werden. Für manche komplexe Algorithmen kann das ein echtes Hindernis darstellen.
- Das Wesen der Eingabedaten und andere Faktoren müssen bestimmt werden, die sich direkt auf die durchgeführten Experimente auswirken. Prinzipiell hat man die drei Möglichkeiten: tatsächliche Daten, zufällige Daten oder extreme Daten verwenden. Mit tatsächlichen Daten kann man die realen Kosten des verwendeten Programms messen. Zufällige Daten geben einem die Gewissheit, dass das Experiment den Algorithmus und nicht die Daten testet. Schließlich gewährleisten extreme Daten, dass das Programm mit jeder Art von Eingaben umgehen kann.
- Wenn man Implementierungen vergleicht, schleichen sich leicht Fehler ein. Vor allem wenn sich die Tests auf unterschiedliche Computer, Compiler
oder Systeme erstrecken oder wenn man größere Programme mit schlecht spezifizierten Eingaben vergleicht.
In der Praxis ist die Analyse nach der empirischen Methode weit verbreitet. Für diesen Zweck sind in modernen Entwicklungsumgebungen oftmals bereits Profiler-Tools[8] integriert. Das Ergebnis dieser Methode ist eine Aussage über die Laufzeit eines Software-Produktes unter bestimmten Bedingungen.
Auch bei einem Projekt zur „Leistungsoptimierung im Nachhinein“ wird in der Regel diese Methode verwendet.
Sobald empirische Untersuchungen unverhältnismäßig viel Zeit erfordern, ist die mathematische Methode gefragt. Für diesen Zweck gibt es die Standard-notation, die sogenannte O-Notation[9] [KePi00, S.46]. Diese wurde bereits 1894 von dem Mathematiker Paul Gustav Heinrich Bachmann (1837-1920) eingeführt und von [Knu76, S.18] für die Analyse von Algorithmen „wieder entdeckt“. Der grundlegende Parameter der O-Notation ist n, die Größe einer bestimmten Ausprägung eines Problems. Die Komplexität oder Laufzeit von einem Algorithmus wird als Funktion von n ausgedrückt.
Das „O“ steht für das englische „o rder“ und gibt eine Größenordnung für das Laufzeitverhalten an. Die Notation O(f(n)) bedeutet, dass die Laufzeit proportional zu höchstens f(n) ist, wenn n hinreichend groß ist [KePi00, S.46]. In der folgenden Tabelle sind die wichtigsten Fälle für Komplexitäten aufgelistet, die Algorithmen haben können. Siehe hierzu [KePi00, S.47] und [Ern00, S.429]:
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 2: Mögliche Komplexitäten von Algorithmen[10] [11]
Bei der „Leistungsoptimierung im Nachhinein“ wird diese Methode wohl nur in Ausnahmefällen angewendet. Für die Beurteilung der Leistungsfähigkeit eines Software-Produktes sind eben Aussagen wie „Das Programm ‚P’ benötigt für die Bearbeitung der Daten ‚D’ genau ‚n’ Sekunden“ für die Marketingabteilung oder den Kunden wohl eher verständlich, als eine Aussage der mathematischen Methode wie zum Beispiel: „Das Programm ‚P’ hat die Komplexität O( log n )“.
Objektorientierte Programme können auf verschiedenartige Weise erarbeitet werden. In [Bau00, S.1] wird dafür folgendes Schichtenmodell angegeben:
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 1: Schichtenmodell zur Programmerarbeitung
Programmerarbeitung auf dem Niveau der Bausteine unterstützt die Forderung nach Wiederverwendbarkeit. Die Überlegung, auf vorgefertigte Komponenten zurückzugreifen, ist bereits mit der Entwicklung symbolischer Programmiersprachen entstanden und wird seitdem in Form von Makros oder Programm-bibliotheken verwirklicht [Bau00, S.1].
Im Rahmen der Objektorientierung wird nun der Gedanke der Wiederverwendung erneut aufgegriffen und forciert. Aus diesem Grunde wird die Betrachtung zu objektorientierten Programmen auf dieser Ebene durchgeführt [Bau00, S.1].
Für den Begriff Baustein wird in [Bau00, S.2] folgende Erläuterung gegeben:
Ein Baustein ist ein bestimmter Typ von Software-Komponenten. Typbildendes Merkmal ist der Aufbau nach dem Open-Closed-Prinzip.
Open Eine Software-Komponente ist offen, wenn sie erweitert werden kann, ohne dass der vorhandene Quellcode verändert werden muss oder existierende Clients davon berührt werden.
Closed Eine Software-Komponente ist abgeschlossen, wenn sie mit einer definierten Schnittstelle für die Wiederverwendung zur Verfügung gestellt werden kann.
Im Rahmen des Konzeptes zur „Leistungsoptimierung im Nachhinein“ wird der Begriff Baustein ausgedehnt. Unter diesen Begriff fallen hier sowohl reine C++-Bausteine[12] als auch Textbausteine (Formulare und Dokumente) sowie komplette Programmbausteine (Hilfsprogramme), die alle ein Ziel verfolgen, nämlich die Wiederverwendung im Rahmen einer Software-Leistungsoptimierung. Alle diese genannten Bausteine erfüllen die Bedingungen für das oben beschriebene Open-Closed-Prinzip.
Eine ausführliche Erläuterung zum Thema Software-Bausteine findet sich in [Bau00]. Weiterführende Informationen finden sich auch bei [GrTh00]. Das Thema „Software-Wiederverwendung“ wird bei [Küf94] ausführlich behandelt.
Das Optimieren der Ausführungsgeschwindigkeit eines Software-Produktes am Ende eines Entwicklungsprojektes oder gar erst nach Freigabe und Auslieferung in der Wartungs- und Pflegephase ist bekanntermaßen sehr zeitaufwendig und teuer. Im Allgemeinen wird davon ausgegangen, dass die Kosten für Änderungen mit dem Projektfortschritt exponentiell steigen [vgl. Beck00, S.21].
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 2: Änderungskosten mit Verlauf des Projektfortschritts
Trotzdem kann man in konkreten Software-Projekten immer wieder beobachten, dass solche Optimierungsaufgaben an das Ende eines Software-Entwicklungsprojektes gestellt werden. In einem Artikel der Zeitschrift IEEE Software [Smith91, S.95] wurde bereits vor über zehn Jahren auf diese Problematik aufmerksam gemacht: „Fixing it later was a viable approach in the 1970s, but today it is dangerous. Performance-Engineering methods fall between the extremes of ‘performance-driven development’ and ‘fixing it later’”.
Dass diese Problematik mehr als zehn Jahre später immer noch aktuell ist, belegt die folgende Aussage aus dem Fachartikel [EvSchDu02, S.74]:
„Examining performance at the end of software development is a common industrial practice, but it can lead to using more expensive and powerful hardware than originally proposed, time-consuming tuning measures, or (in extreme cases) completely redesigning the application…. To avoid such costs, a system’s performance characteristics must be considered throughout the whole software development process”.
Trotz ständig steigender Rechenleistung der Hardware ist eine Leistungsoptimierung von Software-Produkten oftmals unumgänglich. Wie die folgenden Beispiele zeigen, machen es die aktuellen Anforderungen an die Rechengeschwindigkeit und die zu verarbeitende Datenmengen nach wie vor erforderlich, dass die Ressource „Hardware“ von der Software möglichst effizient genutzt wird.
Multimedia-Applikationen
Bilddaten sollen möglichst 3-dimensional sein und eine möglichst große und realistische Auflösung mit immer mehr Farben besitzen. Bewegte Bilder sind schon fast selbstverständlich. Solche Anforderungen sind selbst mit den neuesten Rechnergenerationen nur dann zu erfüllen, wenn effiziente Algorithmen eingesetzt werden.
Datenbanken
In Datenbanken steigt die Menge der zu verwaltenden Daten drastisch an. Immer mehr Informationen werden gesammelt. Dies erfordert auch immer komplexere Auswertungen, deren Ergebnisse dennoch möglichst sofort verfügbar sein sollen.
Hardware-Geschwindigkeit
Die Hardware wird immer schneller und liefert immer größere Mengen an Daten. So steigt nicht nur die Datenmenge selbst, sondern auch die Zeit wird immer kürzer, in der die Daten verarbeitet werden müssen.
Betriebssystem
In einer Multitasking-Umgebung belegen gleichzeitig mehrere Programme einen Teil der verfügbaren Gesamtrechenleistung eines Rechners. Auch die Anforderungen an diese Programme werden immer komplexer. Dennoch erwartet der Anwender, dass er von der Ressourcen-Aufteilung möglichst nichts bemerkt und alle Programme scheinbar „gleichzeitig“ ablaufen.
Weitere Beispiele finden sich bei [Joh98, S.280] in dem Artikel „High-Speed, Wide Area, Data Intensive Computing: A Ten Year Retrospective”.
Der Trend, eine Leistungsoptimierung erst am Ende oder nach der Freigabe eines Software-Projektes durchzuführen, hat sich aus verschiedenen Motiven heraus entwickelt. Zwei davon werden im Folgenden vorgestellt.
Die Projektleitung hat die Aufgabe, die Software termingerecht zu den geplanten Kosten und in der geplanten Qualität auszuliefern [Brö00, S.291]. Der notwendige Zeitaufwand für die Entwicklung einer leistungsoptimierten Software ist jedoch sehr schwer abzuschätzen.
Durch die Strategie der „Leistungsoptimierung im Nachhinein“ hofft man nun, das Risiko einer Terminüberschreitung zu reduzieren. Erst nachdem die Entwicklung der Funktionalität eines Software-Produktes abgeschlossen ist, wird die restliche zur Verfügung stehende Projektzeit genutzt, um Optimierungsmaßnahmen durchzuführen. Fehlt diese Zeit, dann wird die Optimierung häufig erst nach Freigabe der Software in der Wartungs- und Pflegephase des Software-Produktes durchgeführt. Siehe auch [Bal01, S.1091].
Gordon Moore (ehem. Gründer und CEO von Intel®) hat 1965 die Prognose aufgestellt, dass sich die Transistordichte integrierter Schaltkreise alle 18 Monate verdoppelt [Moo65]. Entsprechend erhöht sich auch die Leistungsfähigkeit von Mikroprozessoren. Diese durch die Medien als „Mooresches Gesetz“ bekannt gewordene Prognose hat bis heute seine Gültigkeit bewahrheitet und wird dies nach Einschätzung von Moore selbst [Moo03] auch für die nächsten zehn Jahre noch tun.
Bei der Strategie der „Leistungsoptimierung im Nachhinein“ beginnt man mit den Leistungstests erst am Ende der Software-Entwicklung, um dann (unter Einsatz aktueller Hardware) eventuell noch vorhandene Leistungsdefizite aufzuspüren und durch Software-Optimierung zu beseitigen.
Die Informatik-Theorie empfiehlt, eine Leistungsoptimierung möglichst frühzeitig im Software-Entwicklungsprozess zu berücksichtigen. Wie man in den Kapiteln 3.2.1 und 3.2.2 sehen kann, sind in der Praxis immer noch Motive vorhanden, diese Ratschläge und Empfehlungen zu ignorieren und erst in der letzten Phase einer Software-Entwicklung mit der Leistungsoptimierung zu beginnen.
Die Verbesserung der „Leistungsoptimierung im Nachhinein“ hat als Hauptziel, den dabei anfallenden Entwicklungsaufwand möglichst gering zu halten. Um dieses Ziel zu erreichen, sind zuvor mehrere Arbeitsschritte durchzuführen.
- Zunächst einmal ist es notwendig, die Entwicklungsphasen einer „Leistungsoptimierung im Nachhinein“ zu kennen. Diese Entwicklungsphasen werden daher in Kapitel 4 (Prozess zur „Leistungsoptimierung im Nachhinein“) analysiert und aufgezeigt.
- Auf Grundlage der analysierten Entwicklungsphasen ist ein ganzheitliches Konzept zu entwerfen, welches das Ziel hat, den notwendigen Zeitbedarf und damit die Entwicklungskosten für die Optimierung eines Software-Produktes zu reduzieren. In Kapitel 5 wird dazu ein Konzept zur „Leistungsoptimierung im Nachhinein“ vorgestellt.
- Durch die Umsetzung des Konzeptes zur „Leistungsoptimierung im Nachhinein“ sollen Rahmenbedingungen geschaffen werden, die dem Entwickler helfen, die erforderlichen Aufgaben effizienter zu realisieren. Diese Umsetzung wird in Kapitel 6 durch die Entwicklung eines Optimierungskataloges beschrieben.
- Durch die Anwendung des Konzepts zur „Leistungsoptimierung im Nachhinein“ ist festzustellen, ob das angestrebte Ziel, nämlich die Reduzierung des Entwicklungsaufwandes, erfüllt werden kann. In Kapitel 7 werden die Erfahrungen mit einer solchen Anwendung beschrieben.
Software-Produkte werden selten vor der ersten Freigabe optimiert. Sobald ein Produkt funktionsfähig ist, wird es freigegeben. Die Optimierung bleibt der Wartung vorbehalten [Bal01, S.1091].
In [Ger02, S.7] wird der Prozess zur „Leistungsoptimierung im Nachhinein“ folgendermaßen dargestellt:
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 3: Der Software-Optimierungsprozess
Die im Folgenden beschriebenen Entwicklungsphasen lehnen sich an die aus der Theorie bekannten Entwicklungsphasen eines Software-Projektes an [Bal01, S.51ff]. Diese wurden jedoch an die besonderen Anforderungen und Aufgaben einer „Leistungsoptimierung im Nachhinein“ angepasst.
Der Prozess zur „Leistungsoptimierung im Nachhinein“ lässt sich in folgende Entwicklungsphasen unterteilen:
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 4: Prozess zur „Leistungsoptimierung im Nachhinein“
Bevor mit der eigentlichen Optimierung begonnen werden kann, muss durch eine Funktionsanalyse ermittelt werden, welche Teilfunktionen eines Software-Produktes optimiert werden müssen. Für jede dieser Teilfunktionen ist ein Leistungsziel festzulegen. Die Analyseergebnisse und Projektziele sind in einem Lastenheft zu beschreiben. Anschließend kann eine Aufwandsabschätzung erfolgen.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 5: Abläufe in der Planungsphase
Durch die Funktionsanalyse soll ermittelt werden, welche Teilfunktionen eines Software-Produktes in Bezug auf die Geschwindigkeit als zu langsam eingestuft und optimiert werden sollen. Ein Software-Produkt komplett zu optimieren wäre viel zu teuer und auch wenig sinnvoll, da es immer Programmteile gibt, die keinen Einfluss auf das Gesamtlaufzeitverhalten des Programms haben, weil diese beispielsweise recht selten oder nur in Sonderfällen aufgerufen werden.
Im Folgenden werden mögliche Gründe genannt, die dazu führen, dass ein Software-Produkt oder eine Software-Funktion als zu langsam eingestuft wird:
- Der Benutzer wird in seinem „Eingabefluss“ gebremst (Sanduhr).
- Der Benutzer empfindet die Ausführungsgeschwindigkeit einer Funktion des Programms als zu langsam.
- Ein direkter Leistungsvergleich zwischen gleichen Funktionen unterschiedlicher Programme auf gleicher Hardware ergibt Laufzeitunterschiede.
- Eine Funktion ist zu langsam, wenn dadurch andere Funktionen, die in Wechselwirkung zu dieser agieren, in ihrer Ausführung gebremst werden. Beispiel: Eine Funktion schreibt Datenblöcke in einen Puffer, eine andere Funktion liest und entfernt diese Daten wieder. Ist die Lesefunktion langsamer als die Schreibfunktion, läuft der Datenpuffer voll. Die Schreibfunktion muss also warten bis im Datenpuffer wieder Platz ist.
- Eine Funktion ist zu langsam, wenn eine Hardware-Komponente die Daten (z.B. Bilddaten einer Kamera) schneller liefert, als die Funktion sie abarbeiten kann.
Eine Funktionsanalyse wird zumeist im Rahmen einer Besprechung durchgeführt. Neben den Entwicklern und Projektleitern können die Teilnehmer auch aus Kunden oder Vertriebsleuten bestehen.
Die Geschwindigkeitsoptimierung einer Software ist eine Aufgabe, die kein klares Abschlusskriterium hat. Selbst eine bereits optimierte Software kann mit entsprechend hohem Aufwand meist noch weiter optimiert werden. Damit ein Optimierungsprojekt dennoch nicht zu einem Endlosprojekt wird, ist es wichtig, bereits bei Projektbeginn ein Maß für das zu erreichende Ziel zu finden. Dies kann beispielsweise durch Festlegung von Kennzahlen erfolgen, die angeben, um welchen Leistungsfaktor eine Teilfunktion optimiert werden soll. Dabei ist es empfehlenswert, für jede Teilfunktion jeweils ein Minimum und ein Maximum anzugeben.
Das Lastenheft ist das Ergebnisdokument der Planungsphase. In der Defini-tionsphase wird das Lastenheft dann zum Pflichtenheft erweitert und verfeinert [Bal01, S.62].
Für die Aufgabe der „Leistungsoptimierung im Nachhinein“ empfiehlt sich für den Inhalt des Lastenheftes folgendes Gliederungsschema:
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 4: Gliederungsschema für das Lastenheft
Die Aufwandsabschätzung dient zur groben Festlegung des Entwicklungsaufwands für die im Lastenheft festgelegten Anforderungen. Eine ausführliche Übersicht über vorhandene Schätzmethoden findet sich bei [Bal01, S.73ff], [Kro97, S.219ff] und [Brö00 S.292ff].
Eine Aufwandsabschätzung an dieser Stelle des Projektes durchzuführen ist eine schwierige Aufgabe. Bei einer Abschätzung müssen viele Faktoren berücksichtigt werden. Wie stark diese Faktoren die Abschätzung beeinflussen ist von Erfahrungswerten abhängig. Aufgrund der hohen Komplexität, die sich bei der Aufgabe „Leistungsoptimierung im Nachhinein“ ergibt, sind die Schätzwerte meist relativ ungenau. Für eine Verbesserung der Abschätzung sollten die Schätzwerte im Laufe des Projektes aktualisiert werden.
Im Folgenden wird eine Auswahl an Einflussfaktoren vorgestellt, die man bei einer Aufwandsabschätzung berücksichtigen kann:
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 5: Einflussfaktoren bei der Aufwandsabschätzung[13]
In der Definitionsphase werden die Anforderungen für das optimierte Software-Produkt näher definiert. Das Ergebnis der Definitionsphase ist ein Pflichtenheft (verfeinertes Lastenheft). Das Pflichtenheft ist die Basis für die Abnahme des fertigen Produktes [Bal01, S.113].
Durch Festlegen der Produktumgebung wird bestimmt, auf welcher Hardware-Plattform das optimierte Software-Produkt einsetzbar sein muss. Ebenso werden die Leistungsanforderungen an das Software-Produkt festgelegt. Die Ergebnisse werden in einem Pflichtenheft festgehalten.
Abbildung in dieser Leseprobe nicht enthalten
Abbildung 6: Abläufe in der Definitionsphase
Mit Festlegung der Produktumgebung wird angegeben, auf welcher Rechnerplattform das Software-Produkt lauffähig sein muss. Diese Angaben sind notwendig, da die Möglichkeiten zur Software-Optimierung abhängig von der verwendeten Hardware-Plattform und dem eingesetzten Betriebssystem sein kann. Folgende Angaben sind für die Definition der Produktumgebung von Bedeutung:
Abbildung in dieser Leseprobe nicht enthalten
Tabelle 6: Angaben zur Produktumgebung
Die Basisanforderungen leiten sich aus den Angaben des Lastenheftes ab. Dieses enthält Angaben zu den zu optimierenden Teilfunktionen sowie zu den zu erreichenden Leistungszielen. Diese Anforderungen werden hier ergänzt bzw. verfeinert.
Falls sich durch die Leistungsoptimierung der Software Änderungen an den Schnittstellen ergeben, dann sind diese Änderungen ebenfalls hier zu beschreiben.
[...]
[1] Sammlung von Optimierungsbausteinen zur Unterstützung des Software-Entwicklers bei Software-Optimierungsprojekten.
[2] Version eines Software-Produktes, welches eine minimale Grundfunktionalität bietet und durch zusätzliche Funktionalitäten erweitert werden kann.
[3] Komponenten in unterschiedlichen Formen (wie C++-Klasse, Formular, etc.) zur Unterstützung eines Optimierungsprozesses.
[4] Testprozess zur Durchführung einer Leistungsbewertung.
[5] Darunter versteht man im Allgemeinen die Zusammensetzung von Software-Programmen aus Standardkomponenten unterschiedlicher Hersteller.
[6] Vorgang einer Leistungsbewertung
[7] Ein Test, der die korrekte und vollständige Funktionalität eines Software-Produktes nachweist.
[8] Software-Tool zum Ermitteln der Ausführungsgeschwindigkeit und Ausführungshäufigkeit von Codeanweisungen in einem Software-Programm.
[9] Die O-Notation trifft Aussagen über die Komplexität bzw. Ordnung von Algorithmen.
[10] Das „Sieb des Eratosthenes“ ist ein Algorithmus zur Ermittlung von Primzahlen.
[11] Bei dem Problem des Handlungsreisenden sind n Städte und deren Entfernung zueinander gegeben. Es ist der kürzeste Weg zu bestimmen, bei dem jede Stadt genau einmal besucht wird.
[12] Komponenten, die als Untermenge der Optimierungsbausteine aus C++-Klassen bestehen.
[13] Software-Tool zum Ermitteln von Leistungsschwächen in Software-Programmen.
Kommentare