9. Februar 2024 von Yelle Lieder
Green Coding – Guidelines für die Entwicklung nachhaltiger Software
An Richtlinien und Empfehlungen für nachhaltige Software mangelt es nicht. Im Gegenteil, es gibt so viele Kriterienkataloge und Best-Practice-Listen, die sich täglich weiterentwickeln, dass eine 40-Stunden-Woche kaum ausreicht, um den Überblick zu behalten. Das Handbook of Sustainable Design of Digital Services des Institute for Sustainable IT mit 516 Kriterien, die W3C Web Sustainability Guidelines mit 93 Empfehlungen, der Kriterienkatalog des Umweltcampus Birkenfeld mit 20 Kriterien, die Pattern Library der Green Software Foundation mit 53 Pattern und das Tactics-Archiv der VU Amsterdam mit 95 Beispielen sind nur eine Auswahl der verfügbaren Quellen. Sie sind nützlich, um die Bandbreite der Handlungsoptionen kennen zu lernen. Für die tägliche Arbeit sind sie jedoch aufgrund ihres Umfangs eher überfordernd und lenken aufgrund der Granularität der diskutierten Entscheidungen stark vom Wesentlichen ab.
Bei adesso haben uns daher Gedanken darüber gemacht, was für uns wirklich wichtig ist. Das Ergebnis sind 9 (+2) Leitlinien für die Entwicklung nachhaltiger Software, die ich im Folgenden vorstellen möchte.
Datenbasierte Lebenszyklusbetrachtung
Nachhaltige Software betrachtet nicht nur das Laufzeitverhalten, sondern die Umweltauswirkungen über den gesamten Lebenszyklus. Durch Simulation, Berechnung und Messung der tatsächlichen Umweltauswirkungen in allen Phasen des Lebenszyklus können unerwünschte Wechselwirkungen erkannt und adäquat behandelt werden. Beispielsweise kann eine Technologie im Betrieb sehr effizient sein, aber im Leerlauf oder beim Hochfahren unverhältnismäßig viele Ressourcen verbrauchen. Bei Anwendungen mit konstant hoher Last ohne dynamische Skalierung wäre ein effizientes Laufzeitverhalten wichtig. Wird dagegen regelmäßig auf Null skaliert, kann der Overhead für das Booten in relevantem Umfang ins Gewicht fallen. Nur durch eine Bewertung über den gesamten Lebenszyklus können solche Zielkonflikte aufgedeckt und bei der Implementierung berücksichtigt werden. Es sollte daher oberstes Gebot sein, alle Entscheidungen nicht nur im Kontext einer einzelnen Lebenszyklusphase zu treffen, sondern immer auf Basis der zuvor erhobenen Daten. Mehr zur Messung der Nachhaltigkeit von Software erfahrt ihr in diesem Blog-Beitrag.
Caching
Nachhaltige Software speichert Ergebnisse zwischen und reduziert die Anzahl redundanter Operationen. Häufig verwendete Daten sollten schnell verfügbar sein. Dadurch können redundante Berechnungen oder sogar teure Inferenzen in KI-Modellen reduziert werden. Ein solches Caching kann sowohl in Frontend-Anwendungen im Browser als auch in Backend-APIs oder auf http-Ebene eingesetzt werden. Indem Daten schnell verfügbar gemacht werden, ohne dass sie erneut über das Netzwerk übertragen oder Datenbanken erneut durchsucht werden müssen, können Rechenleistung und Stromverbrauch von Netzwerkgeräten eingespart werden.
Datensparsamkeit
Nachhaltige Software ist datensparsam. Indem die Menge der gespeicherten, verarbeiteten und übertragenen Daten reduziert wird, wird weniger physische Hardware für die Verarbeitung und Speicherung benötigt. Zudem wird weniger Energie verbraucht, da die beteiligte Hardware weniger Rechenleistung erbringen muss und weniger Speichermedien ständig mit Strom versorgt werden müssen. Konkrete Strategien für mehr Datensparsamkeit sind beispielsweise Komprimierung, Batching von Operationen, Bereitstellung von Filtern in APIs oder Paginierung - sowohl im Frontend als auch in APIs.
Carbon Awareness
Nachhaltige Software leistet weniger, wenn kein grüner Strom verfügbar ist. Durch die Ausrichtung der Ausführung ressourcenintensiver Prozesse an der Verfügbarkeit erneuerbarer Energien können die CO2-Emissionen des Systembetriebs je nach Region um bis zu 40 Prozent reduziert werden. Dabei können Prozesse sowohl zeitlich verschoben werden, um von einer besseren CO2-Intensität vor Ort zu profitieren, wenn die Prozesse nicht zeitkritisch sind, als auch an anderen Orten durchgeführt werden, an denen aktuell mehr erneuerbare Energie produziert wird, wenn es sich um zeitkritische Prozesse handelt. Es wird geschätzt, dass bis zu 30 Prozent aller Arbeitslasten nicht zeitkritisch sind und sich daher für eine Verlagerung eignen.
Mobile First
Nachhaltige Software ist kompatibel und leistungsfähig auf mobilen Geräten. Die Entwicklung nach dem „Small-First“-Paradigma führt nicht nur zu laufzeiteffizienten Lösungen. Durch die Kompatibilität auf mehr Endgeräten kann auch eine höhere Abwärtskompatibilität erreicht werden, das heißt, Nutzerinnen und Nutzer müssen sich seltener neue Hardware anschaffen, um aktuelle Software nutzen zu können. Da auf mobilen Systemen oft weniger Ressourcen zur Verfügung stehen, müssen diese noch sparsamer eingesetzt werden. Dies gilt sowohl für Prozessoren und Speicher als auch für Bandbreiten und Displays.
Effiziente Algorithmen und Datenstrukturen
Nachhaltige Software verwendet effiziente und problemadäquate Algorithmen und Datenstrukturen. Durch den Verzicht auf generische Lösungen können anwendungsspezifische Stärken im Bereich des Ressourcenverbrauchs spezifischer Alternativen genutzt werden. Insbesondere wenn Skaleneffekte zum Tragen kommen, kann sich eine Optimierung der gewählten Algorithmen und Datenstrukturen lohnen. Allzu oft werden einfach mehrere Listen oder Arrays geschachtelt, wo alternative Datentypen - beispielsweise Hash-Tabellen - problemadäquater und effizienter wären. Ebenso häufig werden Standard-Sortieralgorithmen verwendet, ohne die Beschaffenheit der konkreten Daten zu berücksichtigen. Die Folge sind unnötig viele CPU-Zyklen oder Speicherbelegungen, die den Ressourcenverbrauch des Systems erhöhen.
Over-Engineering vermeiden
Nachhaltige Software vermeidet gezielt Over-Engineering. Durch technologische Suffizienz kann der Ressourcenverbrauch reduziert werden, indem nur das getan wird, was wirklich notwendig ist. Dazu gehört eine angemessene Komplexität der Implementierungen und der gewählten Technologien ebenso wie die Reduktion des Funktionsumfangs auf das Wesentliche. Konkrete Entscheidungen zur Vermeidung von Over-Engineering können beispielsweise approximative Programmierung, Feature-Toggling, bedarfsgerechte Protokollierung oder plugin-orientierte Architekturen sein.
Obsoleszenz Vermeidung
Nachhaltige Software wirkt der technischen Obsoleszenz entgegen. Durch Strategien zur Vermeidung von Obsoleszenz - im Gegensatz zu Veralterung - können Systeme länger genutzt werden. Dadurch müssen seltener neue Systeme entwickelt werden, was den Ressourcenverbrauch schont. Diese Förderung der Langlebigkeit gilt sowohl für Hardware als auch für Software. Zur Förderung der Langlebigkeit von Hardware ist vor allem auf Abwärtskompatibilität zu achten, d.h. Software sollte so geringe Leistungsanforderungen haben, dass sie auch auf älterer Hardware lauffähig ist. Langlebigkeit von Software kann durch gezielte Wartungs- und Update-Strategien erreicht werden. Dabei spielt auch die Auswahl von Technologien eine Rolle, die langfristig mit Updates versorgt und weiterentwickelt werden. Geeignete Instrumente zur Technologieauswahl können hier beispielsweise Technologiereifegradmodelle wie die von der NASA entwickelten Technology Readyness Level (TRL) sein. Durch Patterns für gut wartbaren Code - zum Beispiel Single Responsibility Patter, Kapselung und lose Kopplung - kann die Wartbarkeit zudem technisch unterstützt und mit Metriken wie Cycolomatic Complexity, Code Duplication oder Method/Class Length überprüft werden.
Keep it simple
Zukunftsfähige Software ist einfach. Einfach im doppelten Sinne:
- Zum einen muss nachhaltige Software an sich einfach sein. Etablierte und weniger komplexe Lösungen verbrauchen in der Regel weniger Ressourcen. Wer die Funktion einer verfügbaren Bibliothek von Hand nachbaut, wird nur in Ausnahmefällen zu einer leistungsfähigeren Lösung kommen. Das Rad neu zu erfinden lohnt sich aus Nachhaltigkeitssicht daher selten. Einfachheit muss auch bei der Wahl der Technologie gelten. Wenn JSON als Datenformat zur Problemlösung geeignet ist, sollte es schon sehr gute Gründe geben, trotzdem XML zu verwenden. Denn solche komplexeren Datenformate verbrauchen nicht nur mehr Ressourcen beim Parsen, sondern erzeugen auch mehr Datenübertragungs- und Speicherlast.
- Zum anderen ist die Implementierung nachhaltiger Software einfach. Nur eine der vorgestellten Techniken ist wirklich bahnbrechend neu und verursacht zusätzlichen Aufwand. Und selbst dieses neue Carbon-Aware-Paradigma wird durch bestehende Ansätze wie die Separierung von Batch-Jobs - etwa zur Ausführung auf Spot-Instanzen - unterstützt. In vielen Fällen kann Nachhaltigkeit einfach als zusätzliches Kriterium für oder gegen Entscheidungen herangezogen werden, ohne dass relevanter Mehraufwand entsteht. Häufig ergeben sich auch positive Nebeneffekte für andere Qualitätseigenschaften, wie eine bessere Wartbarkeit oder User Experience.
Guidelines für nachhaltige Softwareentwicklung bei adesso
Zusätzlich zu den neun vorgestellten Punkten enthalten unsere internen Guidelines noch die Punkte "Nachhaltige Technologieauswahl" und "Verwendung von ereignisbasierten Patterns". Die Bedeutung und Vorteile dieser beiden Guidelines Items wurden bereits in diesem Blog-Beitrag zur nachhaltigen Softwarearchitektur vorgestellt, weshalb an dieser Stelle auf eine Wiederholung verzichtet wird.
Die vorgestellten Guidelines wurden gemeinsam mit der adesso Software Engineering Community entwickelt, an dieser Stelle vielen Dank an alle Beteiligten für die aktive Mitgestaltung. Sie sind als Orientierung beziehungsweise Handlungsempfehlung und nicht als alleiniger Weg zur Nachhaltigkeit zu verstehen. Unsere Guidelines sollen insbesondere denjenigen Entwicklerinnen und Entwicklern Handlungs- und Entscheidungsmöglichkeiten im Alltag aufzeigen, die bisher weniger Berührungspunkte mit nachhaltiger Software hatten. Sie stellen natürlich keine vollständige Liste möglicher Aktivitäten dar, sind aber aus unserer Sicht die ersten Schritte auf dem Weg zu