Welche Programmiersprachen verbrauchen am wenigsten Strom?
Können uns Daten über den Energieverbrauch etwas über die Qualität unserer Programmiersprachen sagen?
Im letzten Jahr beschloss ein Team von sechs portugiesischen Forschern aus drei verschiedenen Universitäten, diese Frage zu untersuchen, und veröffentlichte schließlich eine Arbeit mit dem Titel „Energy Efficiency Across Programming Languages“. Sie überprüften die Lösungen von 10 Programmierproblemen, die in 27 verschiedenen Sprachen geschrieben waren, und überwachten dabei sorgfältig, wie viel Strom jedes einzelne verbrauchte – sowie die Geschwindigkeit und den Speicherverbrauch.
Speziell verwendeten sie 10 Probleme aus dem Computer Language Benchmarks Game, einem freien Softwareprojekt zum Leistungsvergleich, das einen Standardsatz einfacher algorithmischer Probleme sowie einen Rahmen für die Durchführung von Tests enthält. (Es war früher unter dem Namen „The Great Computer Language Shootout“ bekannt.) „Dies ermöglichte es uns, einen vergleichbaren, repräsentativen und umfangreichen Satz von Programmen zu erhalten… zusammen mit den Kompilierungs-/Ausführungsoptionen und Compiler-Versionen.“
Es war wichtig, eine Vielzahl von Benchmark-Tests durchzuführen, da die Ergebnisse letztendlich je nach Test variierten. So erwies sich beispielsweise die Sprache C insgesamt als die schnellste und energieeffizienteste. Bei dem Benchmark-Test, bei dem eine DNA-Datenbank nach einer bestimmten genetischen Sequenz durchsucht wurde, war Rust jedoch am energieeffizientesten, während C den dritten Platz belegte.
Aber selbst bei diesem Test hängt die „beste“ Sprache davon ab, welches Kriterium man anlegt. Auch in diesem Test war C nur die zweitschnellste Sprache (wiederum hinter Rust). Aber Rust fiel um ganze neun Positionen zurück, wenn die Ergebnisse nach Speicherverbrauch sortiert wurden. Und während Fortran bei diesem Test die zweit-effizienteste Sprache war, fiel sie um ganze sechs Plätze zurück, wenn die Ergebnisse stattdessen nach der Ausführungszeit sortiert wurden.
Eine schnellere Sprache ist nicht immer die energieeffizienteste.
Die Forscher merken an, dass sie die Richtlinien des CLBG-Projekts über Compiler-Versionen und die besten Optimierungs-Flags „streng befolgt“ haben. Der Stromverbrauch wurde mit einem Tool von Intel – dem Running Average Power Limit Tool – gemessen, wobei jedes Programm nicht nur einmal, sondern zehnmal ausgeführt wurde, „um die Auswirkungen von Kaltstarts und Cache-Effekten zu reduzieren und um die Konsistenz der Messungen zu analysieren und Ausreißer zu vermeiden.“ (Aus diesem Grund berichten sie, dass „die gemessenen Ergebnisse recht konsistent sind“.) Für zusätzliche Konsistenz wurden alle Tests auf einem Desktop mit Linux Ubuntu Server 16.10 (Kernel-Version 4.8.0-22-generic), 16 GB RAM und einer 3,20 GHz Haswell Intel Core i5-4460 CPU durchgeführt.
In ihrem Papier nennen die Forscher einige interessante Ergebnisse.
„Lisp verbraucht im Durchschnitt 2.27x mehr Energie (131.34J) als C, während es 2.44x mehr Zeit zur Ausführung benötigt (4926.99ms) und 1.92x mehr Speicher (126.64Mb) im Vergleich zu Pascal.“
Sie verglichen auch die Ergebnisse von kompilierten Sprachen mit interpretierten Sprachen (mit einer separaten Kategorie für Sprachen, die auf virtuellen Maschinen laufen). Das Papier enthält auch einen separaten Vergleich der verschiedenen Programmierparadigmen – einschließlich funktionaler und imperativer Programmierung sowie objektorientierter Programmierung und Skripting.
Ist schneller umweltfreundlicher?
Das Papier nahm die gängige Annahme unter die Lupe, dass ein schnelleres Programm immer weniger Energie verbraucht, und wies darauf hin, dass dies nicht so einfach ist wie das physikalische Gesetz, das besagt, dass E(nergy) = T(time) x P(ower). Das liegt zum Teil daran, dass die Energie nicht gleichmäßig verbraucht wird, stellen die Forscher fest, was sich möglicherweise auf die Arbeit anderer Forscher auswirkt, die untersuchen, ob die Laufzeit eines Programms seinen Energieverbrauch beeinflusst. (In einem ihrer Benchmark-Tests benötigte ein Chapel-Programm 55 Prozent weniger Zeit für die Ausführung als ein gleichwertiges, in Pascal geschriebenes Programm – und dennoch verbrauchte das Pascal-Programm 10 Prozent weniger Energie.
Während es also immer noch die weit verbreitete Meinung gibt, dass der Energieverbrauch sinkt, wenn Programme schneller laufen, stellen die Forscher unmissverständlich fest, dass „eine schnellere Sprache nicht immer die energieeffizienteste ist“
Diese Frage ist schwer zu beantworten, da der Energieverbrauch von vielen Faktoren beeinflusst wird (einschließlich der Qualität des Compilers und der verwendeten Bibliotheken). Letztendlich waren die Forscher jedoch in der Lage, den Energieverbrauch danach aufzuschlüsseln, ob er von der CPU oder vom DRAM verbraucht wurde. Sie kamen zu dem Schluss, dass der größte Teil des Stroms (etwa 88 %) im Durchschnitt von der CPU verbraucht wurde, unabhängig davon, ob das Benchmark-Programm kompiliert, interpretiert oder auf einer virtuellen Maschine ausgeführt wurde.
Interessanterweise zeigten interpretierte Sprachen eine etwas größere Schwankung, wobei die CPU manchmal bis zu 92 % verbrauchte.
Nach der Untersuchung ihrer Ergebnisse kamen die Forscher auch zu dem Schluss, dass die Beziehung zwischen der Spitzennutzung von DRAM und dem Energieverbrauch „fast nicht existent ist“
Die Forschung bietet einige weitere Einblicke in die immerwährende Frage: Ist schneller grüner? Ja, es stimmt, dass „die fünf energieeffizientesten Sprachen ihren Rang beibehalten, wenn sie nach Ausführungszeit sortiert werden, und zwar mit sehr geringen Unterschieden bei den Energie- und Zeitwerten.“
Tatsächlich kam bei neun von zehn Benchmark-Problemen die höchste Punktzahl (sowohl für Geschwindigkeit als auch für Energieeffizienz) von einer der drei insgesamt schnellsten und energieeffizientesten Sprachen – was die Forscher nicht überrascht. „Es ist allgemein bekannt, dass diese drei Top-Sprachen (C, C++ und Rust) in Bezug auf die Ausführungsleistung stark optimiert und effizient sind, wie auch unsere Daten zeigen.“
Bei der Einstufung der anderen 24 Sprachen nach ihrer Laufzeit ergibt sich jedoch nicht die gleiche Reihenfolge wie bei der Einstufung nach Energieeffizienz. „Nur vier Sprachen behalten den gleichen Energie- und Zeit-Rang (OCaml, Haskel, Racket und Python), während die übrigen völlig durcheinander gewürfelt werden.“
Und selbst bei einzelnen Benchmark-Tests gibt es Fälle, in denen die schnellsten Sprachen nicht die energieeffizientesten sind.
Die Vorteile kompilierter Sprachen
Es gab noch weitere interessante Ergebnisse. Kompilierte Sprachen „tendieren dazu“, die energieeffizientesten und schnellsten zu sein – und ihr Papier kann diesen Unterschied sogar mit einer Zahl beziffern. „Im Durchschnitt verbrauchten kompilierte Sprachen 120J für die Ausführung der Lösungen, während dieser Wert für eine virtuelle Maschine und interpretierte Sprachen bei 576J bzw. 2365J lag.“
Die Forscher wendeten dieselbe Präzision auch beim Vergleich der Ausführungszeiten an und kamen zu dem Schluss, dass im Durchschnitt „kompilierte Sprachen 5103ms, Sprachen mit virtueller Maschine 20623ms und interpretierte Sprachen 87614ms benötigten.“
Von den fünf führenden Sprachen in beiden Kategorien waren vier kompiliert. (Die Ausnahme: Java.)
Energieverbrauch | Lauf-Zeit | |
C | 57J | 2019 ms |
Rost | 59J | 2103 ms |
C++ | 77J | 3155 ms |
Ada | 98J | 3740 ms |
Java | 114J | 3821 ms |
Die fünf langsamsten Sprachen waren alle interpretiert: Lua, Python, Perl, Ruby und Typescript. Und die fünf Sprachen, die am meisten Energie verbrauchten, waren ebenfalls interpretiert: Perl, Python, Ruby, JRuby und Lua.
Bei der Manipulation von Zeichenketten mit regulären Ausdrücken entpuppen sich jedoch drei der fünf energieeffizientesten Sprachen als interpretierte Sprachen (TypeScript, JavaScript und PHP), „obwohl sie in anderen Szenarien tendenziell nicht sehr energieeffizient sind.“
Kompilierte Sprachen belegten auch die ersten fünf Plätze beim geringsten Speicherplatzverbrauch.
Sprache | Speicherplatzbedarf |
Pascal | 66Mb |
Go | 69Mb |
C | 77Mb |
Fortran | 82Mb |
C++ | 88Mb |
„Im Durchschnitt, benötigten die kompilierten Sprachen 125 MB, die Sprachen für virtuelle Maschinen 285 MB und die interpretierten Sprachen 426 MB“, berichten die Forscher. Unterdessen belegten interpretierte Sprachen vier der fünf letzten Plätze, was bedeutet, dass sie den meisten Speicherplatz verbrauchten: JRuby, Dart, Lua und Perl. (Obwohl Erlang keine interpretierte Sprache ist, würde sie ebenfalls unter den fünf letzten Plätzen auftauchen, zwischen Dart und Lua).
„Wenn man sie nach ihrem Programmierparadigma sortiert, benötigten die imperativen Sprachen 116Mb, die objektorientierten 249Mb, die funktionalen 251Mb und schließlich die Skriptsprachen 421Mb.“
In der Tat, wenn man die verschiedenen Paradigmen vergleicht, war die imperative Programmierung oft an der Spitze. Ihre Benchmark-Programme verbrauchten im Durchschnitt auch viel weniger Energie – und liefen viel schneller – als die Benchmark-Programme für objektorientierte, funktionale und Scripting-Paradigmen.
Energieverbrauch | Laufzeit | |
Imperativ | 125J | 5585ms |
Objekt-Orientiert | 879J | 32965ms |
Funktional | 1367J | 42740ms |
Scripting | 2320J | 88322 ms |
Aber es gibt viele Faktoren zu berücksichtigen. „Es ist klar, dass verschiedene Programmierparadigmen und sogar Sprachen innerhalb desselben Paradigmas einen völlig unterschiedlichen Einfluss auf Energieverbrauch, Zeit und Speicher haben“, schreiben die Forscher. Welches dieser Faktoren am wichtigsten ist, hängt von Ihrem Szenario ab. (Hintergrundaufgaben brauchen zum Beispiel nicht immer die schnellste Laufzeit…)
Und bei manchen Anwendungen müssen zwei Faktoren berücksichtigt werden – zum Beispiel Energieverbrauch und Ausführungszeit. In diesem Fall „ist C die beste Lösung, da es bei beiden Einzelzielen dominant ist“, schreiben die Forscher. Wenn man versucht, Zeit zu sparen und gleichzeitig weniger Speicher zu verbrauchen, sind C, Pascal und Go „gleichwertig“ – und dasselbe gilt, wenn man alle drei Variablen (Zeit, Energieverbrauch und Speicherverbrauch) im Auge behält. Wenn Sie jedoch nur versuchen, Energie zu sparen und dabei weniger Speicher zu verwenden, sind C oder Pascal die beste Wahl.
Am Ende des Papiers fügen die Forscher hinzu, dass sie für weitere Studien untersuchen möchten, ob der Gesamtspeicherverbrauch über die Zeit besser mit dem Energieverbrauch korreliert.
Sie stellen ihre Daten online zur Verfügung, um künftigen Forschern den Vergleich von z. B. .NET-Sprachen oder JVM-Sprachen zu erleichtern. Für Entwickler, die mit mobilen Anwendungen, Internet-of-Things-Systemen oder anderen Anwendungen arbeiten, die nur eine begrenzte Stromversorgung benötigen, ist der Stromverbrauch ein wichtiges Anliegen.
Aber am Ende könnte die Studie Programmierer auch mit dem zurücklassen, was sie am meisten hassen: Unklarheit. Die Forscher berichten, dass es auf die Frage nach der besten Programmiersprache keine konkrete und endgültige Antwort gibt.
„Obwohl die energieeffizienteste Sprache in jedem Benchmark fast immer die schnellste ist, gibt es keine Sprache, die durchgängig besser ist als die anderen“, so die Forscher. „Die Situation, in der eine Sprache verwendet wird, ist ein zentraler Aspekt, um zu bestimmen, ob diese Sprache die energieeffizienteste Option ist.“