30. Mai 2023 von Yelle Lieder
Nachhaltigkeit von Programmiersprachen: Lieber Java als TypeScript?
Nachhaltigkeit und Effizienz von Technologien sind auf den ersten Blick untrennbar verbunden. Schließlich kann steigende Effizienz Ressourcen und Strom sparen und so Umweltauswirkungen reduzieren. Diesem Narrativ folgend wird im Kontext digitaler Nachhaltigkeit häufig eine Studie zitiert, die die Energieeffizienz von Programmiersprachen untersucht. Aber sind effiziente Programmiersprachen wirklich nachhaltiger?
Was hat es mit effizienten Programmiersprachen auf sich?
Das Paper „Energy efficiency across programming languages“ von Pereira et al. (2017) versucht darauf eine Antwort zu liefern. Es untersucht Programmiersprachen auf Geschwindigkeit, Energieverbrauch und Memory Usage, also die Auslastung des Arbeitsspeichers (RAM). Dazu werden Toy Programs aus dem Computer Language Benchmarks Game ausgeführt und zur Laufzeit vermessen.
Die Ergebnisse sind wenig überraschend. Im Paper heißt es dazu: „Es ist allgemein bekannt, dass die Top-3-Sprachen (C, C++ und Rust) stark optimiert und effizient in der Ausführung sind, wie auch unsere Daten zeigen.“ Das vollständige Ranking ist in der folgenden Abbildung zu sehen.
Ist Energieeffizienz zur Laufzeit eine sinnvolle Metrik?
Zunächst die offensichtliche Erkenntnis, welche die Autoren selbst immer wieder betonen: Es besteht kein linearer Zusammenhang zwischen Ausführungszeit und Energieverbrauch. Code, der doppelt so schnell ausgeführt wird, verbraucht also nicht immer halb so viel Energie. Die Antwort auf eine der Forschungsfragen „Ist die schnellere Sprache immer die energieeffizienteste?“ lautet daher klar: „Nein, eine schnellere Sprache ist nicht immer die energieeffizienteste.“ Im Interview mit einem der Autoren werden die Ergebnisse noch einmal in Kontext gesetzt.
Die Autoren der verwendeten Toy Programs schreiben zudem frei übersetzt: „Wir sind zutiefst uninteressiert an der Behauptung, dass die Messungen einiger weniger kleiner Programme die relative Leistung von Programmiersprachen […] definieren.“ Dies bezieht sich darauf, dass die Programme nicht mit produktiv eingesetzter Software vergleichbar sind, oft ganz andere Anforderungsprofile haben und die Ergebnisse deshalb nicht übertragbar sind. Es gibt wichtige Charakteristiken von Sprachen, die in einem solchen Test nicht hinreichend berücksichtigt werden. Das Ausführen von Algorithmen ist eine Sache, aber die Anwendung in komplexen, verteilten Systemen mit vielen Datenübertragungen, asynchronen Prozessen und Zugriff auf Langzeitspeicher ist etwas völlig anderes.
Weitere Aspekte, die differenzierter betrachtet werden müssen, sind:
- Kompilierung und Interpretierung von Source- in Binärcode: So beinhalten die Ergebnisse des Papers etwa nicht den Energieaufwand, um Java-Code zu kompilieren oder TypeScript vor der Ausführung in JavaScript zu kompilieren. Diese zusätzlichen Schritte fallen zwar nicht in allen Fällen an, müssen jedoch für einen fairen Vergleich berücksichtigt werden.
- Portabilität: Muss eine Anwendung in C erst angepasst werden, um auf einem anderen System lauffähig zu sein, kostet dieser Umbau wieder Ressourcen, etwa auf Rechnern von Entwickelnden und in Deployment Pipelines.
- Debugging: Im Flask Debug Mode zur Laufzeit kurz Änderungen verproben bringt einen geringeren Zeit- und Ressourcenaufwand mit sich, als ein ganzes Rust-Projekt mit allen Crates zu kompilieren, bevor der Bugfix überprüft werden kann. Zudem haben Wartbarkeit und Lesbarkeit einen Einfluss darauf, wie viel Ressourcen in Anpassungen von Code investiert werden müssen. Das Debugging in den unterschiedlichen Sprachen kann also auch unterschiedlich viel Arbeitszeit und damit Ressourcen und Energie kosten.
Eine reine Orientierung an der Tabelle ist also fehlleitend, vielmehr müssen Entwickelnde sich immer am gesamten Lebenszyklus und dem Anwendungsfall der zu entwickelnden Software orientieren.
Wie steht es um die Performanz von Frameworks?
Der zweite Vergleich, der häufig zitiert wird, sind die Web Framework Benchmarks. Sie beinhalten Tasks wie JSON-Serialisierung, Datenbankzugriff und serverseitige Template-Erstellung und vergleichen Performance, Latenz und Overhead – nicht aber Energieeffizienz. Es werden realistischere und alltagsnähere Vergleiche angestellt und unterschiedliche Kombinationen von Tasks verprobt. Verglichen mit der Testung einzelner Sprachen sehen hier die Ergebnisse beim Vergleich von Frameworks deutlich anders aus. Im Testszenario Fortune beispielsweise schneidet das Framework NodeJS (JavaScript) besser ab als Spring (Java). Ähnlich sieht es mit Django (Python) und Rails (Ruby) aus. Natürlich sind Node und Spring nicht ohne weiteres substituierbar, der Vergleich zeigt jedoch, dass für bestimmte Settings auch „weniger effiziente Sprachen“ eine gute Wahl sein können.
Auch dieser Vergleich lässt einige der oben adressierten Fragen offen. Jedes produktive System hat andere Laufzeitanforderungen, nutzt Funktionalitäten der Frameworks mehr, weniger oder gar nicht. Auch wird hier wieder nicht der gesamte Entwicklungszyklus betrachtet. Eine Entscheidung für oder gegen Technologien allein auf Basis von Energieeffizienzbenchmarks zur Laufzeit ist zu kurz gedacht. Sonst müsste auch diskutiert werden, ob zugunsten der Nachhaltigkeit auf objektorientierte Programmierung verzichtet und bevorzugt Monolithen mit enger Kopplung entwickelt werden sollten. Denn die Forschung zeigt, dass prozedural programmierte Monolithen (schlecht wartbar, skalierbar …) weniger Overhead zur Laufzeit erzeugen als objektorientierte modulare Systeme. Die Diskussion lässt sich auch auf Open Source und Low oder No Code ausweiten, aber das führt hier zu weit.
Wie relevant ist die Effizienz von Programmiersprachen?
Auf wissenschaftlichen Konferenzen und in Fachgremien im Bereich Sustainable IT spielt die Effizienz einzelner Technologien eine untergeordnete Rolle. Zwar verlieren sich gelegentlich Diskussionen in den Effizienzvergleichen von Algorithmen oder Webtechnologien, insgesamt machen die Neuveröffentlichungen dazu jedoch einen kleinen Anteil aus. Der Fokus liegt auf dem effizienten Einsatz von Technologien, der Vermeidung von Verschwendung, Hardware, Energiequellen oder dem sparsamen Umgang mit Rechenleistung. Warum hat die Effizienz aber keine höhere Relevanz?
- Reifegrad: Effizienz von Software ist längst sehr gut verstanden. Wir wissen aus Benchmarks, welche Technologien wie effizient sind. Außerdem haben wir historisch aufgrund der knappen Verfügbarkeit von Rechenleistung gute Erfahrungen damit gemacht, wie man performante Software entwickelt. Wir sind im Bereich Effizienz also einfach deutlich weiter als beispielsweise beim verantwortungsvollen Umgang mit IT-Hardware oder der Nutzung erneuerbarer Energien.
- Wirkungsgrad: Verglichen mit Maßnahmen wie der Verwendung erneuerbarer Energien oder der verlängerten Nutzungsdauer von Hardware, haben Effizienzsteigerungen einzelner Softwaretechnologien häufig nur einen geringen Wirkungsgrad. Nach dem Prinzip der Pareto-Effizienz konzentriert man sich also zunächst auf die Handlungsoptionen mit hohem Wirkungsgrad und geringen Investitionskosten, bevor im Bereich Effizienz kostspielige Optimierungen mit geringem Wirkungsgrad angegangen werden.
- Zielkonflikte: Durch die Effizienzsteigerung von Technologie werden die Technologien häufiger und intensiver genutzt, weil die Kosten für die Nutzung sinken oder die Nutzung schlicht komfortabler – weil schneller – ist. Dieser Zielkonflikt wird auch als Rebound-Effekt bezeichnet. Effizienz führt also nicht immer automatisch zu mehr Nachhaltigkeit.
- Vergleichbarkeit: Nur wenige Softwaretechnologien sind direkt vergleichbar. Die beiden im Titel genannten haben verschiedene Eigenschaften, Funktionen und Ökosysteme und sind auf unterschiedliche Problemstellungen optimiert, weshalb eher selten eine Wahl zwischen genau diesen beiden getroffen werden muss. Eine Liste, die nur Laufzeitaspekte schwer vergleichbarer Technologien betrachtet, darf also nicht allein für Technologieauswahlentscheidungen verwendet werden. Was eher hilft, ist der Vergleich konkreter Eigenschaften in Abhängigkeit vom Anwendungsfall. Eine Hilfestellung dazu können etwa die Real World Example Apps geben, mit denen sich Kombinationen von Technologien verproben lassen. Noch zielführender ist aber der Vergleich unterschiedlicher Konfigurationen derselben Technologie, etwa im Vergleich zur Default-Konfiguration, um das Beste aus jeder Technologie rauszuholen.
Worauf es tatsächlich ankommt
Der Fokus auf Effizienz allein ist irreführend. Solange wir nicht darüber nachdenken, woher der Strom kommt und wie viel Hardware wir mit unserer Software auslasten, sind die Verbesserungspotenziale durch reine Effizienz einzelner Technologien zu gering. Die Diskussion über Programmiersprachen lenkt von der eigentlichen Problematik (Elektroschrott, Verschwendung von Rechenleistung, Energiequellen) ab. Zudem müssen wir aufhören „Nachhaltigkeit“ und „Effizienz“ synonym zu verwenden.
Eine Betrachtung der ganzen Lebenszykluskosten digitaler Lösungen, angefangen bei der Hardware für Entwicklung und Betrieb über Anforderungen, Konzept und Design, Technologieauswahl und Entwicklung bis zu Betrieb und Wartung, ist, was es stattdessen braucht. Auch der Software-Entwicklungsprozess – also der Einfluss von Arbeitsgeräten, Reisen, Testumgebungen und Pipelines – ist noch viel zu wenig erforscht. Eindimensionale Betrachtungen bringen uns deshalb der Erreichung von Nachhaltigkeitszielen keinen Schritt näher.
Welche Ziele sich adesso in puncto Nachhaltigkeit gesetzt hat, welche Maßnahmen wir umsetzen wollen und welche Chancen und Herausforderungen für unser Unternehmen damit in Verbindung stehen, zeigen wir euch auf unserer Website.