Die Erlaubnis, digitale oder gedruckte Kopien dieser Arbeit ganz oder teilweise für den persönlichen Gebrauch oder den Unterricht im Unterricht anzufertigen, wird ohne Gebühr erteilt, vorausgesetzt, dass Kopien nicht zu Gewinnzwecken oder zu kommerziellen Zwecken hergestellt oder vertrieben werden und diese Kopien diesen Hinweis und das vollständige Zitat auf der ersten Seite tragen . Urheberrechte für Komponenten dieser Arbeit, die anderen als ACM gehört, muss respektiert werden. Das Abstrahieren mit Kredit ist erlaubt. Um anderweitig zu kopieren oder neu zu veröffentlichen, auf Servern zu posten oder an Listen weiterzuverteilen, bedarf es der vorherigen ausdrücklichen Genehmigung und/oder einer Gebühr. Fordern Sie Berechtigungen von permissions@acm.org an. SLE’17, 23.–24. Oktober 2017, Vancouver, BC, Kanada © 2017 Verein für Rechenmaschinen. ACM ISBN 978-1-4503-5525-4/17/10. . . $15,00 https://doi.org/10.1145/3136014.3136031 Abstrakt Dieses Papier stellt eine Studie über die Laufzeit, den Speicherverbrauch und den Energieverbrauch von siebenundzwanzig bekannten Softwaresprachen vor. Wir überwachen die Leistung solcher Sprachen anhand von zehn verschiedenen Programmierproblemen, die in jeder der Sprachen ausgedrückt werden. Unsere Ergebnisse zeigen interessante Erkenntnisse, wie z. B. langsamere/schnellere Sprachen, die weniger/mehr Energie verbrauchen, und wie die Speichernutzung den Energieverbrauch beeinflusst. Wir zeigen, wie unsere Ergebnisse genutzt werden können, um Software-Ingenieuren bei der Entscheidung zu unterstützen, welche Sprache zu verwenden ist, wenn es um Energieeffizienz geht. CCS-Konzepte • Software und ihre Technik → Soft- Warenleistung; Allgemeine Programmiersprachen; Schlagworte Energieeffizienz, Programmiersprachen, Lan- guage Benchmarking, Grüne Software ACM-Referenzformat: Rui Pereira, Marco Couto, Francisco Ribeiro, Rui Rua, Jácome Cunha, João Paulo Fernandes und João Saraiva. 2017. Energieeffizienz über Programmiersprachen hinweg. In Proceedings of SLE’17, Vancouver, BC, Kanada, 23.–24. Oktober 2017, 12 Seiten. https://doi.org/10.1145/3136014.3136031 1. Einleitung Software Language Engineering bietet leistungsstarke Techniken und Tools zum Entwerfen, Implementieren und Entwickeln von Softwaresprachen. Solche Techniken zielen darauf ab, die Produktivität von Programmierern zu verbessern – indem fortgeschrittene Merkmale in das Sprachdesign integriert werden, wie zum Beispiel leistungsstarke modulare und Typensysteme – und solche Software effizient auszuführen – indem zum Beispiel aggressive Compiler-Optimierungen entwickelt werden. Tatsächlich wurden die meisten Techniken mit dem Hauptziel entwickelt, Softwareentwicklern bei der Erstellung schnellerer Programme zu helfen. Tatsächlich war die Leistung von Softwaresprachen im letzten Jahrhundert in fast allen Fällen gleichbedeutend mit schneller Ausführungszeit (eingebettete Systeme waren wahrscheinlich die einzige Ausnahme). In diesem Jahrhundert ändert sich diese Realität schnell und der Energieverbrauch von Software wird zu einem Hauptanliegen für Computerhersteller, Softwaresprachingenieure, Programmierer und sogar normale Computerbenutzer. Heutzutage ist es üblich, dass Benutzer von Mobiltelefonen (die leistungsstarke Computer sind) vermeiden, CPU-intensive Anwendungen zu verwenden, nur um Batterie/Energie zu sparen. Während die Sorge um die Energieeffizienz der Computer von den Hardwareherstellern begann, wurde sie schnell auch zu einer Sorge für Softwareentwickler [27]. Tatsächlich handelt es sich hierbei um ein junges und intensives Forschungsgebiet, in dem mehrere Techniken zur Analyse und Optimierung des Energieverbrauchs von Softwaresystemen entwickelt werden. Solche Techniken liefern bereits Wissen über die Energieeffizienz von Datenstrukturen [ 14 , 26] und Android-Sprache [ 24], die Energieauswirkungen verschiedener Programmierpraktiken sowohl in mobilen [ 17 , 21 , 30 ] als auch in Desktop-Anwendungen [25, 31], die Energieeffizienz von Anwendungen im gleichen Umfang [ 2 , 16] oder sogar die Vorhersage des Energieverbrauchs in mehreren Softwaresystemen [4, 13], neben mehreren anderen Arbeiten. Eine interessante Frage, die sich im Bereich der Software-Energieeffizienz häufig stellt, ist, ob ein schnelleres Programm auch ein energieeffizientes Programm ist oder nicht. Wenn die Antwort ja lautet, dann bedeutet die Optimierung eines Programms auf Geschwindigkeit auch eine Optimierung auf Energie, und genau das hat die Compiler-Konstruktionsgemeinschaft seit den Anfängen von Softwaresprachen kaum getan. Der Energieverbrauch hängt jedoch nicht nur von der Ausführungszeit ab, wie die Gleichung Ener äy = Zeit × Leistung zeigt. Tatsächlich gibt es mehrere Forschungsarbeiten, die unterschiedliche Ergebnisse zu diesem Thema zeigen [1, 20, 26, 28, 34, 37]. Eine ähnliche Frage stellt sich beim Vergleich von Softwaresprachen: Ist eine schnellere Sprache eine grünere? Der Vergleich von Softwaresprachen ist jedoch eine äußerst komplexe Aufgabe, da die Leistung einer Sprache von der Qualität ihres Compilers, ihrer virtuellen Maschine, ihres Garbage Collectors, der verfügbaren Bibliotheken usw. beeinflusst wird. Tatsächlich kann ein Softwareprogramm durch die Verbesserung seiner Quelle schneller werden Code, sondern auch "nur" seine Bibliotheken und/oder seinen Compiler optimieren. In diesem Papier analysieren wir die Leistung von siebenundzwanzig Softwaresprachen. Wir betrachten zehn verschiedene Programmierprobleme, die in jeder der Sprachen ausgedrückt werden, und folgen genau demselben Algorithmus, wie er im Computer Language Benchmark Game (CLBG) [11] definiert ist. Wir kompilieren/ausführen solche Programme unter Verwendung modernster Compiler, virtueller Maschinen, Interpreter und Bibliotheken für jede der 27 Sprachen. Anschließend analysieren wir die Leistung der verschiedenen Implementierungen unter Berücksichtigung von drei Variablen: Ausführungszeit, Speicherverbrauch und Energieverbrauch. Darüber hinaus analysieren wir diese Ergebnisse nach dem Ausführungstyp der Sprachen (kompiliert, virtuelle Maschine und interpretiert) und dem verwendeten Programmierparadigma (imperativ, funktional, objektorientiert, Skripterstellung). Für jede der Ausführungsarten und Programmierparadigmen haben wir eine Rangliste der Softwaresprachen gemäß jeder berücksichtigten Variablen zusammengestellt. Unsere Ergebnisse zeigen interessante Erkenntnisse, wie langsamere/schnellere Softwaresprachen, die weniger/mehr Energie verbrauchen, und wie die Speichernutzung den Energieverbrauch beeinflusst. Darüber hinaus erörtern wir, wie solche Ergebnisse verwendet werden können, um Softwareingenieuren Unterstützung bei der Entscheidung zu bieten, welche Sprache zu verwenden ist, wenn Energieeffizienz ein Anliegen ist. Diese Arbeit baut auf früheren Arbeiten [6] auf, in denen ein Framework vorgestellt wurde, das die Überwachung des Energieverbrauchs von ausführbaren Softwareprogrammen ermöglicht. In dieser Arbeit wurde das C-basierte Framework verwendet, um eine vorläufige Rangfolge von zehn Sprachen zu definieren (wobei nur Energie berücksichtigt wurde). Wir verwenden das Energiemonitoring-Framework (kurz beschrieben in Abschnitt 2.2) erneut, um die Energieeffizienz von 27 Sprachen und (fast) 270 Programmen zu analysieren. Wir haben es auch erweitert, um auch den Speicherverbrauch zu überwachen. Dieses Dokument ist wie folgt aufgebaut: Abschnitt 2 stellt die detaillierten Schritte unserer Methodik zum Messen und Vergleichen der Energieeffizienz in Softwaresprachen vor, gefolgt von einer Präsentation der Ergebnisse. Abschnitt 3 enthält die Analyse und Diskussion der erzielten Ergebnisse, wobei wir zunächst analysieren, ob die Ausführungszeitleistung Energieeffizienz impliziert, dann die Beziehung zwischen Spitzenspeichernutzung und Speicherenergieverbrauch untersuchen und schließlich eine Diskussion darüber präsentieren, wie Energie, Zeit und Speicher beziehen sich in den 27 Softwaresprachen. In Abschnitt 4 diskutieren wir die Bedrohungen für die Aussagekraft unserer Studie. Abschnitt 5 stellt die diesbezügliche Arbeit vor, und schließlich stellen wir in Abschnitt 6 die Schlussfolgerungen unserer Arbeit vor. 2 Energiemessung in Softwaresprachen Die anfängliche Motivation und der primäre Fokus dieser Arbeit ist es, die Energieeffizienz über verschiedene Programmiersprachen hinweg zu verstehen. Dies mag wie eine einfache Aufgabe erscheinen, aber es ist nicht so trivial, wie es klingt. Um die Energieeffizienz zwischen Programmiersprachen richtig vergleichen zu können, müssen wir verschiedene vergleichbare Implementierungen mit einer guten Darstellung verschiedener Probleme/Lösungen erhalten. Vor diesem Hintergrund versuchen wir zunächst, die folgende Forschungsfrage zu beantworten: • RQ1: Können wir die Energieeffizienz von Softwaresprachen vergleichen? Dadurch werden wir Ergebnisse haben, in denen wir tatsächlich die Energieeffizienz gängiger Programmiersprachen vergleichen können. Mit diesen Ergebnissen können wir auch die Beziehungen zwischen Energieverbrauch, Ausführungszeit und Speichernutzung untersuchen. In den folgenden Unterabschnitten werden die zur Beantwortung dieser Frage verwendete Methodik und die Ergebnisse, die wir erhalten haben, detailliert beschrieben. 2.1 Das Benchmark-Spiel für Computersprachen Um einen vergleichbaren, repräsentativen und umfangreichen Satz von Programmen zu erhalten, die in vielen der beliebtesten und am weitesten verbreiteten Programmiersprachen geschrieben sind, haben wir The Computer Language Benchmarks Game [11] untersucht. (CLBG). Die CLBG-Initiative umfasst einen Rahmen zum Ausführen, Testen und Vergleichen implementierter kohärenter Lösungen für eine Reihe bekannter, vielfältiger Programmierprobleme. Die allgemeine Motivation besteht darin, Lösungen innerhalb und zwischen verschiedenen Programmiersprachen vergleichen zu können. Während die Perspektiven für den Lösungsvergleich ursprünglich im Wesentlichen die Laufzeitleistung analysiert haben, wird CLBG neuerdings auch eingesetzt, um die Energieeffizienz von Software zu untersuchen [6, 20, 24]. In seiner aktuellen Entwicklungsphase hat das CLBG Lösungen für 13 Benchmark-Probleme gesammelt, sodass Lösungen für jedes dieser Probleme einen bestimmten Algorithmus und spezifische Implementierungsrichtlinien berücksichtigen müssen. Lösungen für jedes Problem werden in höchstens 28 verschiedenen Programmiersprachen ausgedrückt. Die vollständige Liste der Benchmark-Probleme im CLBG deckt verschiedene Computerprobleme ab, wie in Tabelle 1 beschrieben. Zusätzlich wird die vollständige Liste der Programmiersprachen im CLBG in Tabelle 2 gezeigt, sortiert nach ihren Paradigmen. 2.2 Design und Ausführung Unsere Fallstudie zur Analyse der Energieeffizienz von Softwaresprachen basiert auf dem CLBG. Tabellen 1 & 2 Von den 28 im CLBG berücksichtigten Sprachen haben wir Smalltalk ausgeschlossen, da der Compiler für diese Sprache proprietär ist. Außerdem haben wir zur Vergleichbarkeit Benchmark-Probleme verworfen, deren Sprachabdeckung unter der Schwelle von 80 % liegt. Unter Sprachabdeckung verstehen wir für jedes Benchmark-Problem den Prozentsatz der Programmiersprachen (von 27), in denen Lösungen dafür verfügbar sind. Diese Kriterien schlossen Chameneos-Redux, Meteor-Contest und Threadring aus unserer Studie aus. Wir haben dann die effizienteste (d. h. schnellste) Version des Quellcodes in jedem der verbleibenden 10 Benchmark-Probleme für alle 27 betrachteten Programmiersprachen gesammelt. Die CLBG-Dokumentation enthält auch Informationen über die spezifische Compiler-/Runner-Version, die für jede Sprache verwendet wird, sowie über die berücksichtigten Kompilierungs-/Ausführungsoptionen (z. B. Optimierungs-Flags zur Kompilierungs-/Laufzeit). Wir haben diese Anweisungen strikt befolgt und die richtigen Compilerversionen installiert und auch sichergestellt, dass jede Lösung mit den gleichen Optionen kompiliert/ausgeführt wurde, die im CLBG verwendet wurden. Sobald wir die richtigen Compiler- und Benchmark-Lösungen für jede Sprache hatten, testeten wir jede einzeln, um sicherzustellen, dass wir sie ohne Fehler ausführen konnten und dass die Ausgabe der erwarteten entsprach. Der nächste Schritt bestand darin, die Informationen über den Energieverbrauch, die Ausführungszeit und die maximale Speicherauslastung für jede der kompilierbaren und ausführbaren Lösungen in jeder Sprache zu sammeln. Es ist anzumerken, dass das CLBG bereits gemessene Informationen sowohl zur Ausführungszeit als auch zur Spitzenspeichernutzung enthält. Wir haben beide gemessen, nicht nur um die Übereinstimmung unserer Ergebnisse mit dem CLBG zu überprüfen, sondern auch, weil unterschiedliche Hardwarespezifikationen zu unterschiedlichen Ergebnissen führen würden. Zur Messung des Energieverbrauchs haben wir das Tool Running Average Power Limit (RAPL) von Intel [ 9 ] verwendet, das in der Lage ist, genaue Energieschätzungen auf sehr feinkörniger Ebene zu liefern, wie es bereits bewiesen wurde [ 12 , 29]. Außerdem ermöglicht die aktuelle Version von RAPL, dass es von jedem Programm aus aufgerufen werden kann, das in C und Java geschrieben ist (über jRAPL [22]). Um die Sprachen richtig vergleichen zu können, mussten wir die Energie erfassen, die durch eine einzelne Ausführung einer bestimmten Lösung verbraucht wurde. Dazu haben wir den Systemfunktionsaufruf in C verwendet, der die als Argumente angegebenen Stringwerte ausführt; in unserem Fall der Befehl, der zum Ausführen einer Benchmark-Lösung erforderlich ist (z. B. wird die in Python geschriebene Binärbaumlösung durch Schreiben des Befehls /usr/bin/python binarytrees.py 21 ausgeführt). Der Energieverbrauch einer Lösung ist dann die durch den Systemaufruf verbrauchte Energie, die wir mit RAPL-Funktionsaufrufen gemessen haben. Der Gesamtprozess (also der Workflow unseres Energiemess-Frameworks 1) ist in Listing 1 beschrieben. Listing 1 Listing 1. Gesamtprozess des Energiemessrahmens. Fussnote: 1 Der Messrahmen und die vollständigen Ergebnisse sind öffentlich zugänglich unter https://sites.google.com/view/energyfficiency-languages Um sicherzustellen, dass der Overhead unseres Mess-Frameworks mit der Systemfunktion vernachlässigbar oder nicht vorhanden ist, verglichen mit der tatsächlichen Messung mit RAPL im Quellcode eines Programms, entwerfen wir ein einfaches Experiment. Es bestand aus der Messung des Energieverbrauchs innerhalb einer C- und einer Java-Sprachlösung unter Verwendung von RAPL bzw. jRAPL und dem Vergleich der Ergebnisse mit den Messungen aus unserem C-Sprachen-Energiemess-Framework. Wir fanden die resultierenden Unterschiede unbedeutend und daher vernachlässigbar, daher schließen wir, dass wir dieses Framework verwenden könnten, ohne uns um Ungenauigkeiten bei den Energiemessungen kümmern zu müssen. Außerdem haben wir uns dafür entschieden, den Energieverbrauch und die Ausführungszeit einer Lösung gemeinsam zu messen, da der Aufwand für jede Messung gleich ist und dies die erhaltenen Werte nicht beeinflussen sollte. Die Speicherauslastung einer Lösung wurde mit dem Time-Tool erfasst, das in Unix-basierten Systemen verfügbar ist. Dieses Tool führt ein als Argument angegebenes Programm aus und fasst die von diesem Programm verwendeten Systemressourcen zusammen, einschließlich der Spitze der Speichernutzung. Jede Benchmark-Lösung wurde 10 Mal ausgeführt und gemessen, um 10 Energieverbrauchs- und Ausführungszeitproben zu erhalten. Wir haben dies getan, um die Auswirkungen von Kaltstarts und Cache-Effekten zu reduzieren und um die Konsistenz der Messungen analysieren und Ausreißer vermeiden zu können. Wir haben den gleichen Ansatz verfolgt, als wir Ergebnisse für die Speichernutzung gesammelt haben. Bei einigen Benchmark-Problemen konnten wir für bestimmte Programmiersprachen keine Ergebnisse erhalten. In einigen Fällen war für das Benchmark-Problem kein Quellcode verfügbar (d. h. es wurde keine Implementierung in einer konkreten Sprache bereitgestellt, die eine Sprachabdeckung von weniger als 100 widerspiegelt).2 In anderen Fällen wurde der Code tatsächlich bereitgestellt, aber entweder war der Code selbst bereits fehlerhaft oder konnte nicht kompiliert oder ausgeführt werden, wie in CLBG dokumentiert, oder wir konnten ihn trotz aller Bemühungen nicht ausführen, z. B. aufgrund fehlender Bibliotheken .3 Von nun an beziehen wir uns für jedes Benchmark-Problem als seine Ausführungsabdeckung auf den Prozentsatz der (besten) Lösungen dafür, die wir tatsächlich erfolgreich ausführen konnten. Alle Studien wurden auf einem Desktop mit den folgenden Spezifikationen durchgeführt: Betriebssystem Linux Ubuntu Server 16.10, Kernelversion 4.8.0-22-generisch, mit 16 GB RAM, Haswell Intel(R) Core(TM) i5-4460 CPU @ 3.20 GHz. 2.3 Ergebnisse Die Ergebnisse unserer Studie werden teilweise in diesem Abschnitt gezeigt, der Rest im Online-Anhang zu diesem Papier 1. Tabelle 3 und die Tabellen ganz links unter Ergebnisse – A. Datentabellen im Anhang enthalten die gemessenen Daten von verschiedenen Benchmark-Lösungen. Wir zeigen nur die Ergebnisse für Binärbäume, Fannkuch-Redux und Fasta innerhalb des Papiers, die ersten 3 alphabetisch geordnet. Jede Zeile in einer Tabelle repräsentiert eine der 27 gemessenen Programmiersprachen. Die 4 Spalten ganz rechts, von links nach rechts, stellen die Durchschnittswerte für die verbrauchte Energie (Joule), die Ausführungszeit (Millisekunden), das Verhältnis zwischen Energie und Zeit und die Menge der Spitzenspeicherauslastung in MB dar. Der Energiewert ist die Summe aus CPU- und DRAM-Energieverbrauch. Darüber hinaus kann das Verhältnis auch als durchschnittliche Leistung, ausgedrückt in Kilowatt (kW), angesehen werden. Die Zeilen sind nach dem Energieverbrauch der Programmiersprache sortiert, vom niedrigsten zum höchsten. Schließlich enthalten die Tabellen ganz rechts unter Ergebnisse – A. Datentabellen die Standardabweichung und Durchschnittswerte für unsere gemessene CPU, DRAM und Zeit, sodass wir die Varianz verstehen können. Die erste Spalte gibt den Namen der Programmiersprachen an, denen entweder ein (c), (i) oder (v) vorangestellt ist, wodurch sie entweder als kompilierte, interpretierte oder virtuelle Maschinensprache klassifiziert werden. In einigen Fällen folgt dem Namen der Programmiersprache ein ↑x /↓y- und/oder ⇑x /⇓y-Symbol. Der erste Satz von Pfeilen zeigt an, dass die Sprache um x Positionen (↑x) nach oben oder um y Positionen (↓y) nach unten gehen würde, wenn sie nach der Ausführungszeit geordnet wäre. Zum Beispiel ist Fortran in Tabelle 3 für den Fasta-Benchmark die zweitenergieeffizienteste Sprache, fällt aber um 6 Positionen nach unten, wenn es nach Ausführungszeit geordnet wird. Der zweite Satz von Pfeilen gibt an, dass die Sprache um x Positionen (⇑x) nach oben oder um y Positionen (⇓y) nach unten gehen würde, wenn sie entsprechend ihrer maximalen Speichernutzung geordnet würde. Betrachtet man denselben Beispiel-Benchmark, so würde Rust, obwohl er am energieeffizientesten ist, 9 Positionen verlieren, wenn er nach der Spitzenspeicherauslastung geordnet wird. Tabelle 4 zeigt die globalen Ergebnisse (im Durchschnitt) für Energie, Zeit und Mb, normalisiert auf die effizienteste Sprache in dieser Kategorie. Da die pidigits-Benchmark-Lösungen nur weniger als die Hälfte der abgedeckten Sprachen enthielten, haben wir diese für die globalen Ergebnisse nicht berücksichtigt. Die Basiswerte sind wie folgt: Energie für C ist 57,86 J, Zeit für C ist 2019,26 ms und Mb für Pascal ist 65,96 Mb. Beispielsweise verbraucht Lisp im Durchschnitt 2,27-mal mehr Energie (131,34 J) als C, während es im Vergleich zu Pascal 2,44-mal mehr Zeit für die Ausführung (4926,99 ms) und 1,92-mal mehr Speicher (126,64 MB) benötigt. Um die Daten besser zu visualisieren und zu interpretieren, haben wir auch zwei verschiedene Sätze grafischer Daten für jeden der Benchmarks generiert. Der erste Satz, Abbildungen 1-3 und die Abbildungen ganz links unter Ergebnisse - C. Energie- und Zeitdiagramme im Anhang, enthält die Ergebnisse jeder Sprache für einen Benchmark, der aus drei gemeinsamen Teilen besteht: einem Balkendiagramm, einem Liniendiagramm, und ein Streudiagramm. Die Balken stellen die von den Sprachen verbrauchte Energie dar, wobei der CPU-Energieverbrauch in der unteren Hälfte in blau gepunkteten Balken und der DRAM-Energieverbrauch in der oberen Hälfte in orangefarbenen durchgehenden Balken dargestellt sind und die linke y-Achse die durchschnittlichen Joule darstellt. Die Ausführungszeit wird durch das Liniendiagramm dargestellt, wobei die rechte Y-Achse die durchschnittliche Zeit in Millisekunden darstellt. Die Verbindung dieser beiden Diagramme ermöglicht es uns, die Beziehung zwischen Energie und Zeit besser zu verstehen. Schließlich stellt ein Streudiagramm über beiden das Verhältnis zwischen verbrauchter Energie und Ausführungszeit dar. Das Verhältnisdiagramm ermöglicht es uns zu verstehen, ob die Beziehung zwischen Energie und Zeit in allen Sprachen konsistent ist. Eine Variation dieser Werte weist darauf hin, dass der Energieverbrauch nicht direkt proportional zur Zeit ist, sondern von der Sprache und/oder der Benchmark-Lösung abhängt. Der zweite Satz, Abbildungen 4-6 und die Abbildungen ganz rechts unter Ergebnisse – C. Energie- und Zeitdiagramme im Anhang, besteht aus zwei Teilen: einem Balkendiagramm und einem Liniendiagramm. Die blauen Balken stellen den Energieverbrauch des DRAM für jede der Sprachen dar, wobei die linke y-Achse die durchschnittlichen Joules darstellt. Das orangefarbene Liniendiagramm stellt die maximale Speicherauslastung für jede Sprache dar, wobei die rechte Y-Achse den durchschnittlichen MB darstellt. Die Verbindung dieser beiden ermöglicht es uns, die Beziehung zwischen dem DRAM-Energieverbrauch und der Spitzenspeichernutzung für jede Sprache in jedem Benchmark zu betrachten. Indem wir uns an das CLBG wandten, konnten wir eine große Menge an Software-Programmiersprachen verwenden, die verschiedene Programmierprobleme mit ähnlichen Lösungen lösen. Dies ermöglichte es uns, einen vergleichbaren, repräsentativen und umfangreichen Satz von Programmen zu erhalten, die in mehreren der beliebtesten Sprachen geschrieben wurden, zusammen mit den Kompilierungs-/Ausführungsoptionen und Compiler-Versionen. Zusammen mit unserem Energiemess-Framework, das das genaue Intel RAPL-Tool verwendet, konnten wir den Energieverbrauch und damit die Energieeffizienz von Softwaresprachen messen, analysieren und vergleichen und so RQ1 wie gezeigt mit unserem beantworten Ergebnisse. Darüber hinaus konnten wir auch die Ausführungszeit und die Spitzenspeicherauslastung messen, wodurch wir analysieren konnten, wie diese beiden mit dem Energieverbrauch zusammenhängen. Die Analyse und Diskussion unserer Ergebnisse wird im nächsten Abschnitt gezeigt. 3 Analyse und Diskussion In diesem Abschnitt präsentieren wir eine Analyse und Diskussion der Ergebnisse unserer Studie. Während unser Hauptaugenmerk darauf liegt, die Energieeffizienz in Sprachen zu verstehen, werden wir auch versuchen zu verstehen, wie Energie, Zeit und Gedächtnis zusammenhängen. Darüber hinaus werden wir in diesem Abschnitt versuchen, die folgenden drei Forschungsfragen zu beantworten, jede mit einem eigenen Unterabschnitt. • RQ2: Ist die schnellere Sprache immer die energieeffizienteste? Wenn Sie dies richtig verstehen, wird nicht nur angesprochen, ob Energieeffizienz ein reines Leistungsproblem ist, sondern es Entwicklern auch ermöglichen, besser zu verstehen, wie Energie und Zeit in einer Sprache und zwischen Sprachen zusammenhängen. • RQ3: Wie hängt die Speichernutzung mit dem Energieverbrauch zusammen? Erkenntnisse darüber, wie sich die Speichernutzung auf den Energieverbrauch auswirkt, werden es Entwicklern ermöglichen, besser zu verstehen, wie sie den Speicher verwalten, wenn es um den Energieverbrauch geht. • RQ4: Können wir unter Berücksichtigung von Energie, Zeit und Speicherverbrauch automatisch entscheiden, welche die beste Programmiersprache ist? Oft sind Entwickler mit mehr als einer (möglicherweise begrenzten) Ressource beschäftigt. Zum Beispiel Energie und Zeit, Zeit und Speicherplatz, Energie und Speicherplatz oder alle drei. Durch die Analyse dieser Kompromisse können Entwickler erkennen, welche Programmiersprachen in einem bestimmten Szenario am besten geeignet sind. 3.1 Ist schneller, grüner? Ein weit verbreiteter Irrglaube bei der Analyse des Energieverbrauchs in Software ist, dass sich diese genauso verhält wie die Ausführungszeit. Mit anderen Worten, die Verringerung der Ausführungszeit eines Programms würde die gleiche Menge an Energieeinsparung bewirken. Tatsächlich zeigt die Energiegleichung Energie (J) = Leistung (W) x Zeit(en), dass eine Reduzierung der Zeit eine Reduzierung des Energieverbrauchs bedeutet. Allerdings wirkt sich auch die Potenzvariable der Gleichung, die nicht als Konstante angenommen werden kann, auf die Energie aus. Daher gehen die Schlussfolgerungen zu diesem Thema manchmal auseinander, wobei einige Arbeiten belegen, dass Energie und Zeit in direktem Zusammenhang stehen [37], und auch das Gegenteil beobachtet wurde [20, 28, 34]. Die in den oben genannten Tabellen und Abbildungen präsentierten Daten lassen uns interessante Beobachtungen hinsichtlich der Effizienz von Softwaresprachen ziehen, wenn sowohl der Energieverbrauch als auch die Ausführungszeit berücksichtigt werden. Ähnlich wie [ 1 ] und [ 26] beobachteten wir unterschiedliche Verhaltensweisen für den Energieverbrauch und die Ausführungszeit in verschiedenen Sprachen und Tests. Anhand der Daten in Tabelle 4 können wir sehen, dass die C-Sprache insgesamt die schnellste und energieeffizienteste ist. Dennoch gibt es in einigen spezifischen Benchmarks effizientere Lösungen (z. B. im Fasta-Benchmark ist es die dritteffizienteste und die zweitschnellste). Die Ausführungszeit verhält sich im Vergleich zur Energieeffizienz anders. Die Ergebnisse für die 3 in Tabelle 3 dargestellten Benchmarks (und der Rest im Anhang) zeigen mehrere Szenarien, in denen sich ein bestimmter Rang des Energieverbrauchs der Sprache vom Rang der Ausführungszeit unterscheidet (wie die Pfeile in der ersten Spalte anzeigen). Im Fasta-Benchmark beispielsweise ist die Fortran-Sprache die zweiteffizienteste, während sie bei der Ausführungszeit 6 Plätze einbüßt. Darüber hinaus sehen wir durch Beobachtung der Verhältniswerte in den Abbildungen 1 bis 3 (und den Rest im Anhang unter Ergebnisse – C. Energie- und Zeitdiagramme) deutlich eine erhebliche Variation zwischen den Sprachen. Dies bedeutet, dass die durchschnittliche Leistung nicht konstant ist, was den vorherigen Punkt weiter verstärkt. Mit dieser Variante können wir Sprachen mit sehr ähnlichem Energieverbrauch und völlig unterschiedlichen Ausführungszeiten haben, wie im Fall der Sprachen Pascal und Chapel im Binärbaum-Benchmark, deren Energieverbrauch sich ungefähr um 10% zugunsten von Pascal unterscheidet, während Chapel etwa 55 % weniger Ausführungszeit. Tabelle 3, Abbildungen 1 bis 6 Kompilierte Sprachen sind erwartungsgemäß die schnellsten und energieeffizientesten. Im Durchschnitt verbrauchten kompilierte Sprachen 120 J, um die Lösungen auszuführen, während dieser Wert für virtuelle Maschinen und interpretierte Sprachen 576 J bzw. 2365 J betrug. Diese Tendenz kann auch bei der Ausführungszeit beobachtet werden, da kompilierte Sprachen 5103 ms, Sprachen virtueller Maschinen 20623 ms und interpretierte Sprachen 87614 ms (im Durchschnitt) benötigten. Gruppiert nach den verschiedenen Paradigmen verbrauchten und benötigten die imperativen Sprachen durchschnittlich 125 J und 5585 ms, die objektorientierten 879 J und 32965 ms, die funktionalen 1367 J und 42740 ms und die Skriptsprachen 2320 J und 88322 ms. Darüber hinaus sind die Top-5-Sprachen, die weniger Energie und Zeit zum Ausführen der Lösungen benötigen, C (57J, 2019 ms), Rust (59J, 2103 ms), C++ (77J, 3155 ms), Ada (98J, 3740 ms) und Java (114J , 3821 ms); Von diesen wird nur Java nicht kompiliert. Wie erwartet wurden die unteren 5 Sprachen alle interpretiert: Perl (4604J), Python (4390J), Ruby (4045J), JRuby (2693J) und Lua (2660Js) für Energie; Lua (167416 ms), Python (145178 ms), Perl (132856 ms), Ruby (119832 ms) und TypeScript (93292 ms) für die Zeit. Der CPU-basierte Energieverbrauch stellt immer den Großteil der verbrauchten Energie dar. Im Durchschnitt stellt dieser Wert für die kompilierten Sprachen 88,94 % der verbrauchten Energie dar, wobei der verbleibende Teil dem DRAM zugeordnet ist. Dieser Wert ist für virtuelle Maschinen (88,94 %) und interpretierte Sprachen (87,98 %) sehr ähnlich. Während, wie im letzten Punkt erläutert, der durchschnittliche Gesamtverbrauch für diese 3 Sprachtypen sehr unterschiedlich ist, scheint das Verhältnis zwischen CPU- und DRAM-basiertem Energieverbrauch im Allgemeinen gleich zu bleiben. Dies könnte darauf hindeuten, dass die Optimierung eines Programms zur Reduzierung des CPU-basierten Energieverbrauchs auch den DRAM-basierten Energieverbrauch senkt. Es ist jedoch interessant festzustellen, dass dieser Wert bei interpretierten Sprachen (min. 81,57 %, max. 92,90 %) stärker variiert als bei kompilierten (min. 85,27 %, max. 91,75 %) oder virtuellen Maschinensprachen (min. 86,10 %). , maximal 92,43 %). Mit diesen Ergebnissen können wir versuchen, die in RQ2 aufgeworfene Frage zu beantworten: Ist die schnellere Sprache immer die energieeffizienteste? Tabelle 4 Wenn wir uns nur die Gesamtergebnisse ansehen, die in Tabelle 4 gezeigt werden, können wir sehen, dass die Top 5 der energieeffizientesten Sprachen ihren Rang behalten, wenn sie nach Ausführungszeit sortiert werden, und mit sehr kleinen Unterschieden sowohl bei den Energie- als auch bei den Zeitwerten. Dies ist keine Überraschung, da in 9 von 10 Benchmark-Problemen die schnellste und energieeffizienteste Programmiersprache unter den Top 3 war. Außerdem ist allgemein bekannt, dass diese Top-3-Sprachen (C, C++ und Rust ) sind bekanntermaßen stark optimiert und effizient für die Ausführungsleistung, wie unsere Daten ebenfalls zeigen. Da die Zeit die Energie beeinflusst, hatten wir die Hypothese aufgestellt, dass diese Sprachen auch einen effizienten Energieverbrauch erzeugen würden, da sie einen großen Vorteil bei einer der Variablen haben, die die Energie beeinflussen, selbst wenn sie im Durchschnitt mehr Energie verbrauchen. Wenn wir uns jedoch die verbleibenden Sprachen in Tabelle 4 ansehen, können wir sehen, dass nur 4 Sprachen denselben Energie- und Zeitrang beibehalten (OCaml, Haskel, Racket und Python), während der Rest vollständig gemischt ist. Wenn wir uns außerdem einzelne Benchmarks ansehen, sehen wir viele Fälle, in denen es eine andere Reihenfolge für Energie und Zeit gibt. Darüber hinaus lassen uns die Tabellen in den Ergebnissen - A. Datentabellen im Anhang auch verstehen, dass es auf diese Frage keine konkrete und endgültige Antwort gibt. Obwohl die energieeffizienteste Sprache in jedem Benchmark fast immer die schnellste ist, ist Tatsache, dass es keine Sprache gibt, die konstant besser ist als die anderen. Daraus können wir schließen, dass die Situation, in der eine Sprache verwendet wird, ein zentraler Aspekt ist, um festzustellen, ob diese Sprache die energieeffizienteste Option ist. Beispielsweise scheinen im Regex-Redux-Benchmark, der Strings mit regulären Ausdrücken manipuliert, interpretierte Sprachen eine energieeffiziente Wahl zu sein (TypeScript, JavaScript und PHP, alle interpretiert, sind in den Top 5), obwohl sie es tendenziell nicht sind energieeffizient in anderen Szenarien. Daher lautet die Antwort für RQ2: Nein, eine schnellere Sprache ist nicht immer die energieeffizienteste. 3.2 Auswirkungen des Gedächtnisses auf die Energie Wie wirkt sich die Speichernutzung auf den Energieverbrauch des Speichers aus? Es gibt zwei mögliche Hauptszenarien, die diesen Energieverbrauch beeinflussen können: kontinuierliche Speichernutzung und Spitzenspeichernutzung. Mit den von uns gesammelten Daten werden wir versuchen, das letztere Szenario zu beantworten. Die Top 5 Sprachen, die auch in Tabelle 4 zu sehen sind, die (im Durchschnitt) am wenigsten Speicherplatz benötigten, um die Lösungen auszuführen, waren: Pascal (66 MB), Go (69 MB), C (77 MB), Fortran (82 MB). ) und C++ (88 MB); das sind alles kompilierte Sprachen. Die letzten 5 Sprachen waren: JRuby (1309 MB), Dart (570 MB), Erlang (475 MB), Lua (444 MB) und Perl (437 MB); von diesen ist nur Erlang keine interpretierte Sprache. Im Durchschnitt benötigten die kompilierten Sprachen 125 MB, die Sprachen der virtuellen Maschine 285 MB und die interpretierten 426 MB. Sortiert nach ihrem Programmierparadigma benötigten die imperativen Sprachen 116 MB, die objektorientierten 249 MB, die funktionalen 251 MB und schließlich die Skripterstellung 421 MB. Darüber hinaus waren die Top-5-Sprachen, die den letzten DRAM-Energieverbrauch (Durchschnitt) verbraucht haben: C (5J), Rust (6J), C++ (8J), Ada (10J) und Java (11J); Von diesen ist nur Java keine kompilierte Sprache. Die letzten 5 Sprachen waren: Lua (430J), JRuby (383J), Python (356J), Perl (327J) und Ruby (295J); alle sind interpretierte Sprachen. Im Durchschnitt verbrauchten die kompilierten Sprachen 14 J, die Sprachen der virtuellen Maschine 52 J und die interpretierten Sprachen 236 J. Betrachtet man die visuellen Daten aus den Abbildungen 4-6 und die Abbildungen ganz rechts unter Ergebnisse – C. Energie- und Zeitdiagramme im Anhang, kann man schnell erkennen, dass es keine konsistente Korrelation zwischen dem DRAM-Energieverbrauch und dem zu geben scheint Spitzenspeicherauslastung. Um dies zu verifizieren, haben wir zunächst sowohl den DRAM-Energieverbrauch als auch die maximale Speicherauslastung mit dem Shapiro-Wilk-Test [ 32] auf Normalität getestet. Da die Daten nicht normalverteilt sind, haben wir den Rangkorrelationskoeffizienten nach Spearman [ 38] berechnet. Das Ergebnis war ein Spearman-ρ-Wert von 0,2091, was bedeutet, dass er zwischen keiner linearen Beziehung (ρ = 0) und einer schwachen ansteigenden positiven Beziehung (ρ = 0,3) liegt. Obwohl wir die Möglichkeit einer geringen Korrelation zwischen dem Energieverbrauch des DRAM und der Spitzenspeicherauslastung erwartet haben, waren wir überrascht, dass die Beziehung fast nicht existiert. Als Antwort auf den ersten Teil von RQ3 weist dies also darauf hin, dass der Energieverbrauch des DRAM sehr wenig damit zu tun hat, wie viel Speicher an einem bestimmten Punkt eingespart wird, sondern möglicherweise mehr damit, wie er verwendet wird. Als zukünftige Arbeit möchten wir die kontinuierliche Speichernutzung messen, oder mit anderen Worten, die Gesamtmenge des im Laufe der Zeit verwendeten Speichers, um zu verstehen, ob dies zu einem höheren DRAM-Energieverbrauch führt. Wir erwarten eine stärkere Beziehung zwischen diesen beiden, da Faktoren wie Garbage Collection, Cache-Nutzung, Registerort und die Datenverwaltungseffizienz jeder Sprache (Lesen/Schreiben) einen starken Einfluss auf den Energieverbrauch haben werden. 3.3 Energie vs. Zeit vs. Gedächtnis Es gibt viele Situationen, in denen ein Softwareentwickler eine bestimmte Softwaresprache auswählen muss, um seinen Algorithmus gemäß einigen funktionalen oder nicht funktionalen Anforderungen zu implementieren. Wenn er beispielsweise Software für Wearables entwickelt, ist es wichtig, eine Sprache zu wählen und energiebewusste Techniken anzuwenden, die helfen, den Akku zu schonen. Ein weiteres Beispiel ist die Implementierung von Aufgaben, die im Hintergrund ausgeführt werden. In diesem Fall ist die Ausführungszeit möglicherweise kein Hauptanliegen, und sie können länger dauern als diejenigen, die sich auf die Benutzerinteraktion beziehen. Mit der vierten Forschungsfrage RQ4 versuchen wir zu verstehen, ob es möglich ist, automatisch zu entscheiden, welche die beste Programmiersprache ist, wenn der Energieverbrauch, die Ausführungszeit und die Spitzenspeicherauslastung berücksichtigt werden, die von ihren Programmen global und individuell benötigt werden. Mit anderen Worten, ob es eine „beste“ Programmiersprache für alle drei Merkmale gibt, oder falls nicht, welche die besten in jedem gegebenen Szenario sind. Zu diesem Zweck präsentieren wir in Tabelle 5 einen Vergleich von drei Merkmalen der Sprachen: Energieverbrauch, Ausführungszeit und Spitzenspeichernutzung. Um die Sprachen mit mehr als einem Merkmal gleichzeitig vergleichen zu können, verwenden wir einen Mehrziel-Optimierungsalgorithmus, um diese Sprachen zu sortieren. Dies wird auch Pareto-Optimierung genannt [7 , 8 ]. Es ist notwendig, einen solchen Algorithmus zu verwenden, da es in manchen Fällen vorkommen kann, dass keine Lösung gleichzeitig alle Ziele optimiert. Für unser Beispiel sind Energie, Zeit und Speicher die Optimierungsziele. In diesen Fällen gibt es keine dominante Lösung, aber jede Lösung ist in unserem Fall eine Menge von Softwaresprachen. Hier wird die Lösung als Pareto-Optimum bezeichnet. Wir haben diese Technik und insbesondere die unter [36] verfügbare Software verwendet, um unterschiedliche Rankings für die analysierten Softwaresprachen zu berechnen. In Tabelle 5 präsentieren wir vier multiobjektive Rankings: Zeit & Gedächtnis, Energie & Zeit, Energie & Gedächtnis und Energie & Zeit & Gedächtnis. Für jede Rangfolge stellt jede Zeile eine Pareto-optimale Menge dar, d. h. eine Menge, die die Sprachen enthält, die für die zugrunde liegenden Ziele äquivalent sind. Mit anderen Worten, jede Linie ist ein einzelner Rang oder eine Position. Eine einzelne Softwaresprache in einer Position bedeutet, dass die Sprache eindeutig die beste für die analysierten Merkmale war. Mehrere Sprachen in einer Zeile implizieren, dass ein Unentschieden aufgetreten ist, da sie im Wesentlichen ähnlich sind; Letztendlich neigen die Sprachen jedoch als kleiner Kompromiss leicht zu einem der Ziele gegenüber dem anderen. Die häufigsten Leistungsmerkmale von Softwaresprachen, die zu ihrer Bewertung und Auswahl verwendet werden, sind Ausführungszeit und Speicherverbrauch. Wenn wir diese beiden Eigenschaften bei unserer Bewertung berücksichtigen, sind C, Pascal und Go gleichwertig. Wenn wir jedoch Energie und Zeit berücksichtigen, ist C die beste Lösung, da es in beiden Einzelzielen dominant ist. Wenn wir Energie und Gedächtnis bevorzugen, bilden C und Pascal die Pareto-Optimalmenge. Wenn man schließlich alle drei Merkmale analysiert, ist dieses Szenario sehr ähnlich wie bei Zeit und Gedächtnis. Es ist interessant zu sehen, dass die Mengen bei der Betrachtung von Energie und Zeit normalerweise auf ein Element reduziert werden. Dies bedeutet, dass es möglich ist, tatsächlich zu entscheiden, welche die beste Sprache ist. Dies geschieht möglicherweise, weil es einen mathematischen Zusammenhang zwischen Energie und Zeit gibt und sie daher normalerweise eng beieinander liegen, sodass gemeinsam ist, dass eine Sprache in beiden Zielen gleichzeitig dominiert. Es gibt jedoch Fälle, in denen dies nicht zutrifft. Zum Beispiel ist es für Pascal und Chapel nicht möglich zu entscheiden, welches das Beste ist, da Pascal besser im Energie- und Gedächtnisverbrauch ist, aber schlechter in der Ausführungszeit. In diesen Situationen muss der Entwickler eingreifen und entscheiden, was der wichtigste Aspekt ist, um sich für eine Sprache entscheiden zu können. Es ist auch interessant festzustellen, dass Sprachen wie Pascal bei der Betrachtung des Speicherverbrauchs tendenziell in der Rangliste aufsteigen. Obwohl dies natürlich ist, ist es eine schwierige Analyse, die ohne Informationen wie die, die wir in diesem Papier präsentieren, durchzuführen ist. Angesichts der in Tabelle 5 präsentierten Informationen können wir versuchen, Frage 4 zu beantworten: Können wir automatisch entscheiden, welche die beste Softwaresprache ist, wenn man Energieverbrauch, Zeit und Speicherverbrauch berücksichtigt? Wenn es dem Entwickler nur um die Ausführungszeit und den Energieverbrauch geht, dann ja, es ist fast immer möglich, die beste Sprache zu wählen. Geht es auch noch ums Gedächtnis, ist es leider nicht mehr möglich, sich automatisch für eine Sprache zu entscheiden. In allen anderen Rankings bestehen die meisten Positionen aus einer Reihe von Pareto-optimalen Sprachen, d. h. Sprachen, die aufgrund der zugrunde liegenden Merkmale gleichwertig sind. In diesen Fällen muss der Entwickler eine Entscheidung treffen und berücksichtigen, welche die wichtigsten Merkmale in jedem einzelnen Szenario sind, während er auch alle funktionalen/nicht funktionalen Anforderungen berücksichtigt, die für die Entwicklung der Anwendung erforderlich sind. Dennoch sind die Informationen, die wir in diesem Papier bereitstellen, sehr wichtig, um Sprachen nach Äquivalenz zu gruppieren, wenn die verschiedenen Ziele berücksichtigt werden. Soweit wir wissen, ist dies das erste Mal, dass eine solche Arbeit präsentiert wird. Beachten Sie, dass wir die Informationen zu jedem einzelnen Merkmal in Tabelle 4 bereitstellen, damit der Entwickler jeden einzelnen Satz tatsächlich verstehen kann (wir zeigen solche Informationen nicht in Tabelle 5, um das Papier nicht mit zu vielen Tabellen mit Zahlen zu überladen). Tabelle 5 4 Bedrohungen der Gültigkeit Das Ziel unserer Studie war es, das energetische Verhalten mehrerer Programmiersprachen sowohl zu messen als auch zu verstehen, um einen besseren Einblick darüber zu erhalten, wie bestimmte Sprachen hauptsächlich in Bezug auf Energieverbrauch, aber auch Leistung und Speicher verglichen werden. Wir präsentieren in diesem Unterabschnitt einige Gefahren für die Validität unserer Studie, die in vier Kategorien unterteilt sind [ 3 ], nämlich: Schlussfolgerungsvalidität, interne Validität, Konstruktvalidität und externe Validität. Schlussfolgerung Gültigkeit Aus unserem Experiment geht hervor, dass unterschiedliche Programmierparadigmen und sogar Sprachen innerhalb desselben Paradigmas einen völlig unterschiedlichen Einfluss auf Energieverbrauch, Zeit und Speicher haben. Wir sehen auch interessante Fälle, in denen der energieeffizienteste nicht der schnellste ist, und glauben, dass diese Ergebnisse für Programmierer nützlich sind. Zum besseren Vergleich haben wir nicht nur den CPU-Energieverbrauch gemessen, sondern auch den DRAM-Energieverbrauch. Dadurch konnten wir die Beziehung zwischen dem DRAM-Energieverbrauch und der Spitzenspeicherauslastung besser verstehen und gleichzeitig das Verhalten von Sprachen in Bezug auf den von CPU und DRAM abgeleiteten Energieverbrauch verstehen. Darüber hinaus ist die Art und Weise, wie wir die Sprachen gruppiert haben, so, wie wir es für am natürlichsten hielten, Sprachen zu vergleichen (nach Programmierparadigma und wie die Sprache ausgeführt wird). Daher war dies der gewählte Weg, um die Daten in der Arbeit darzustellen. Trotzdem sind alle Daten vorhanden und eventuelle zukünftige Vergleichsgruppen wie „.NET-Sprachen“ oder „JVM-Sprachen“ können sehr einfach analysiert werden. Interne Gültigkeit Diese Kategorie befasst sich damit, welche Faktoren die Ergebnisse unserer Studie beeinflussen können. Bei der Messung des Energieverbrauchs der verschiedenen Programmiersprachen können neben den unterschiedlichen Implementierungen und den eigentlichen Sprachen auch andere Faktoren zu Variationen beitragen, z. B. bestimmte Versionen eines Interpreters oder einer virtuellen Maschine. Um dies zu vermeiden, haben wir jede Sprache und jede Benchmark-Lösung gleichermaßen ausgeführt. In jedem haben wir den Energieverbrauch (CPU und DRAM), die Ausführungszeit und den Spitzenspeicher zehnmal gemessen, die am weitesten entfernten Ausreißer entfernt und den Median, den Mittelwert, die Standardabweichung sowie die Mindest- und Höchstwerte berechnet. Dadurch konnten wir die besonderen Zustände der getesteten Maschine minimieren, einschließlich unkontrollierbarer Systemprozesse und Software. Die gemessenen Ergebnisse sind jedoch recht konsistent und damit zuverlässig. Darüber hinaus hat sich auch das verwendete Energiemessgerät als sehr genau erwiesen. Konstruktvalidität Wir haben 27 verschiedene Programmiersprachen analysiert, jede mit ungefähr 10 Lösungen für die vorgeschlagenen Probleme, was insgesamt fast 270 verschiedene Fälle ergibt. Diese Lösungen wurden von Experten in jeder der Programmiersprachen entwickelt, mit dem Hauptziel, zu „gewinnen“, indem die beste Lösung für die Ausführungszeit produziert wird. Obwohl die verschiedenen Sprachen unterschiedliche Implementierungen enthalten, wurden sie nach denselben Regeln geschrieben, produzierten alle genau dieselbe Ausgabe und wurden so implementiert, dass sie so schnell und effizient wie möglich sind. Mit diesen unterschiedlichen, aber effizienten Lösungen für dieselben Szenarien können wir die verschiedenen Programmiersprachen auf recht gerechte Weise vergleichen, da sie alle demselben Problem gegenübergestellt wurden. Allerdings könnten bestimmte Paradigmen oder Sprachen für bestimmte Probleme einen Vorteil haben, und andere können in einem nicht so traditionellen Sinne implementiert werden. Dennoch gibt es keinen Grund zu vermuten, dass diese Projekte besser oder schlechter sind als jede andere Art, die wir hätten verwenden können. Externe Validität Wir beschäftigen uns mit der Verallgemeinerung der Ergebnisse. Die erhaltenen Lösungen waren zum Zeitpunkt der Erstellung der Studie die leistungsstärksten. Da die CLBG ein fortlaufender "Wettbewerb" ist, erwarten wir, dass fortschrittlichere und effizientere Lösungen die von uns erhaltenen im Laufe der Zeit ersetzen werden, und sogar die Compiler der Sprachen könnten sich weiterentwickeln. Daher kann dies zusammen mit Messungen in verschiedenen Systemen bei einer Replikation zu leicht unterschiedlichen Ergebniswerten führen. Wenn es jedoch keinen großen Sprung innerhalb der Sprache gibt, unterscheiden sich die Vergleiche möglicherweise nicht wesentlich. Der eigentliche Ansatz und die Methodik, die wir verwendet haben, begünstigen auch einfache Replikationen. Dies kann darauf zurückgeführt werden, dass das CLBG die meisten wichtigen Informationen enthält, die zum Ausführen der Experimente benötigt werden, nämlich: den Quellcode, die Compilerversion und die Kompilierungs-/Ausführungsoptionen. Daher glauben wir, dass diese Ergebnisse weiter verallgemeinert werden können und andere Forscher unsere Methodik für zukünftige Arbeiten replizieren können. 5 Verwandte Arbeiten Die in diesem Papier vorgestellte Arbeit erweitert die von [6] vorgestellte Arbeit, in der der Ansatz zur Überwachung des Energieverbrauchs für verschiedene Programmiersprachen vorgestellt wurde. Schwerpunkt von [6 ] war die Methodik und der Vergleich der CPU-basierten Energieeffizienz in 10 der 28 Sprachen. Wir haben eine umfassendere und tiefer gehende Analyse durchgeführt, da wir nicht nur alle Sprachen einbezogen, sondern auch den DRAM-basierten Energieverbrauch und die Spitzenspeichernutzungswerte einbezogen und eine Diskussion darüber präsentiert haben, wie Energie, Zeit und Energie in Software zusammenhängen, und über verschiedene Sprachen, unterteilt nach Typ und Paradigma. Die CLBG-Benchmark-Lösungen wurden bereits von mehreren Forschungsarbeiten zu Validierungszwecken verwendet. Unter anderem wurde CLGB verwendet, um das dynamische Verhalten von Nicht-Java-JVM-Sprachen [19] zu untersuchen, dynamische Skriptsprachen [ 35] und Compiler-Optimierungen [ 33] zu analysieren oder sogar einen JIT-Compiler für PHP zu bewerten [ 15]. Nach unserem besten Wissen wurde CLGB nur einmal für die Energieverbrauchsanalyse verwendet. In [ 20] verwendeten die Autoren neben anderen Benchmarks die bereitgestellten Haskell-Implementierungen, um die Energieeffizienz von Hakell-Programmen aus Strenge- und Nebenläufigkeitsperspektiven zu analysieren, während sie auch den Energieeinfluss kleiner Implementierungsänderungen analysierten. Die Autoren von [ 24] verwendeten CLBG auch, um JavaScript, Java und C++ in einer Android-Umgebung zu vergleichen. Während mehrere Arbeiten Hinweise darauf zeigten, dass ein zeiteffizienterer Ansatz nicht immer zur energieeffizientesten Lösung führt [1, 20, 24, 26, 28, 34], waren diese Ergebnisse weder der beabsichtigte Fokus noch der Hauptbeitrag, sondern eher der eine Nebenbeobachtung an sich. Wir haben uns darauf konzentriert, diese Frage nach dem Zusammenhang von Energieeffizienz und Zeit zu verstehen und direkt zu beantworten. Dennoch hat das Problem der Energieeffizienz bei Software in den letzten Jahren zunehmend an Interesse gewonnen. Tatsächlich sind Studien mit unterschiedlichen Zielen und in unterschiedlichen Bereichen entstanden, mit der gemeinsamen Vision, zu verstehen, wie Entwicklungsaspekte den Energieverbrauch in diversifizierten Softwaresystemen beeinflussen. Für mobile Anwendungen gibt es beispielsweise Arbeiten, die sich auf die Analyse der Energieeffizienz von Codeblöcken [5, 18] oder einfach auf die Überwachung der zeitlichen Entwicklung des Energieverbrauchs konzentrieren [10]. Andere Studien zielten auf eine weitergehende Energieverbrauchsanalyse ab, indem sie die Energieeffizienz ähnlicher Programme in spezifischen Nutzungsszenarien verglichen [ 4 , 16] oder Schlussfolgerungen zu den energetischen Auswirkungen verschiedener Implementierungsentscheidungen lieferten. Mehrere andere Arbeiten haben gezeigt, dass mehrere Faktoren wie unterschiedliche Entwurfsmuster [21, 30], Codierungspraktiken [20, 25, 28, 31] und Datenstrukturen [14, 22, 23, 26] tatsächlich einen signifikanten Einfluss haben in der Energieeffizienz der Software. 6. Schlussfolgerungen In diesem Artikel stellen wir zunächst eine Analyse und einen Vergleich der Energieeffizienz von 27 bekannten Softwaresprachen aus dem beliebten Software-Repository The Computer Language Benchmarks Game vor. Wir können anhand von 10 verschiedenen Benchmark-Problemen zeigen, welche die energieeffizientesten Softwaresprachen, Ausführungsarten und Paradigmen waren. Indem wir auch die Ausführungszeit und die Spitzenspeicherauslastung gemessen haben, konnten wir beides mit der Energie in Beziehung setzen, um nicht nur zu verstehen, wie sich die Speicherauslastung auf den Energieverbrauch auswirkt, sondern auch, wie Zeit und Energie zusammenhängen. Dadurch konnten wir verstehen, ob eine schnellere Sprache immer die energieeffizienteste ist. Wie wir gesehen haben, ist dies nicht immer der Fall. Schließlich haben Entwickler oft begrenzte Ressourcen und können sich mit mehr als einem Effizienzmerkmal befassen, und wir haben berechnet, welche die besten/schlechtesten Sprachen gemäß einer Kombination der vorherigen drei Merkmale sind: Energie & Zeit, Energie & Spitzenwert Speicher, Zeit & Spitzenwert Gedächtnis und Energie & Zeit & Spitzengedächtnis. Unsere Arbeit trägt zu einem weiteren Sprungbrett bei, um Entwicklern mehr Informationen zur Verfügung zu stellen, damit sie beim Programmieren energiebewusster werden. Danksagungen Wir möchten Luís Cruz (Universität Porto) für seine Hilfe danken. Diese Arbeit wird durch den EFRE – Europäischer Fonds für regionale Entwicklung durch das Operationelle Programm für Wettbewerbsfähigkeit und Internationalisierung – COMPETE 2020-Programm und durch nationale Fonds durch die portugiesische Finanzierungsagentur FCT – Fundação para a Ciência e a Tecnologia im Rahmen des Projekts POCI-01-0145- finanziert. FEDER-016718. Der Erstautor wird auch durch das FCT-Stipendium SFRH/BD/112733/2015 gefördert.