Hallo. Mein Name ist Stas. Bei Domclick beaufsichtige ich die Entwicklung von Backoffice-Diensten für Hypothekarkredite bei der Sberbank.
In letzter Zeit bin ich in allen möglichen Berichten und Podcasts häufig auf den Begriff "Green Code" gestoßen. Nachdem ich im Internet gestöbert und dieses Thema studiert hatte, stellte ich fest, dass dieser Begriff eine Reihe von Techniken bei der Entwicklung und dem Design von Anwendungen beschreibt, die den Stromverbrauch der Geräte reduzieren können, auf denen dieser Code ausgeführt wird.
Mehr oder weniger wird diese Frage normalerweise von Entwicklern mobiler Anwendungen verwirrt, hauptsächlich weil das Gerät, auf dem ihr Code ausgeführt wird, eine begrenzte Akkukapazität hat.
Das Thema ist zu einem ziemlichen "Hype" geworden, und ich habe mich entschlossen herauszufinden, wie genau sich die Prinzipien von "Grün" in der WEB-Entwicklung widerspiegeln können.
Grundprinzipien für das Schreiben von "Green Code"
Nachdem ich viele Berichte und Artikel zu diesem Thema gelesen habe, möchte ich die folgenden Aspekte der Anwendungsentwicklung hervorheben, die sich auf den Stromverbrauch auswirken:
1) Vereinfachung und Optimierung von Algorithmen
Wie oben erwähnt, sollte die Ausführung des Codes zu einem minimalen Energieverbrauch führen. Der optimierte Code wird schneller ausgeführt und erfordert daher weniger Verarbeitungs- und Gerätekühlungskosten.
Versuchen wir, den Unterschied im Energieverbrauch für die Ausführung einer bestimmten Operation im Code zu berechnen - die klassische Sortierung einer Liste. Ich werde die Situation im gegebenen Beispiel absichtlich übertreiben, um den Unterschied in mehr Kontrast zu zeigen.
Nehmen wir eine Blasensorte. Dies ist wahrscheinlich einer der suboptimalsten Wege. Es passt sehr gut zu uns. Lassen Sie uns die Sortierung der Liste berechnen und sehen, wie sich dies auf den Stromverbrauch des MacBook auswirkt. Lassen Sie uns zunächst das Datenarray und die Blasensortierlogik selbst simulieren:
from random import randint
def bubble(array):
for i in range(productNumber-1):
for j in range(productNumber-i-1):
if array[j] > array[j+1]:
buff = array[j]
array[j] = array[j+1]
array[j+1] = buff
productNumber = 60000
products = []
for i in range(productNumber):
products.append(randint(1, 1000))
bubble(products)
print(products)
Um die Auswirkungen der Codeausführung auf den Energieverbrauch zu messen, habe ich das Überwachungssystem iStat Menus 6 (https://bjango.com/mac/istatmenus/) verwendet. Ich habe mein MacBook mit dem Netzwerk verbunden, alle Anwendungen von Drittanbietern geschlossen, eine bestimmte Zeit auf das Aufladen des Akkus gewartet und mit dem Sortieren begonnen: Stromverbrauchsdiagramm
beim Durchführen der Blasensortierung: Sie können
einen deutlichen Anstieg des Stromverbrauchs von 305 Sekunden feststellen . Dies wurde durch die Ausführung unserer nicht optimalen Anfrage verursacht. Zusätzlich wird die Energie für 5 Minuten (305 Sekunden) verbraucht
P = (W2 – W1) × 305 = (17,29 [ ] – 2,9 [ ]) × 305 = 14,39 × 305 = 4389 = 0,0012 * .
Nehmen wir nun an, dass dieser Code versehentlich auf einen Industrieproduktserver gelangt (nehmen wir an, dass der zusätzliche Stromverbrauch auf dem Server der gleiche ist wie auf meinem MacBook und die Abhängigkeit direkt proportional ist) und alle 10 Sekunden mit einer Häufigkeit von 1 ausgeführt wird. Dann bekommen wir ein Jahr mehr Energie :
365 × 24 × 3600 /10 × 0,0012 * = 3 784,32 *.
Angenommen, das Rechenzentrum, in dem sich der Server befindet, wird von einem Heizraum mit Birkenholz als Brennstoff mit Strom versorgt. Beim Verbrennen von 1 m 3 Birkenholz werden 1900 kW * h / m 3 Energie freigesetzt. Natürlich ist der Wirkungsgrad des Kessels nicht 100%, und wenn wir ihn für 75% nehmen, erhalten wir : . Wenn wir einen Baum als regulären Zylinder nehmen, dessen Volumen ist
(3 784,32 / 1900) / 0,75 = 2,66 3
V = Pi × R2 × H
wobei R der Radius des Baumstamms ist, nehmen wir ihn als 0,12 Meter (Durchschnittswert),
H ist die Höhe des Baumstamms, nehmen wir ihn als 3 Meter (Durchschnittswert).
dann bekommen wir: Das bedeutet, dass es Holz in einem Kubikmeter gibt . Damit unser Skript funktioniert, benötigen wir ein Jahr . Zum Vergleich habe ich dieselbe Sortierung mit der Standard-Python-Sortiermethode ( ) durchgeführt. Energieverbrauchsdiagramm bei der Standardsortierung in Python: Bei Anwendung derselben Berechnungslogik (die Spitzendauer betrug 10 Sekunden) erhalten wir: In einem Jahr erhalten wir (unter der Annahme, dass der Vorgang alle 10 Sekunden einmal ausgeführt wird) Oder:
V = 3,14 × 0,0144 × 3 = 0,14 3
1 / 0,14 = 7,14
2,66 3 × 7,14 = 19
.sort()
P = (W2 – W1) × 10 = (3,51 [ ] – 2,9 [ ]) × 10 = 6,1 = 0,0000016 *
365 × 24 × 3600 /10 × 0,0000016 * = 5,05 *
5,05 / 1900 / 0,75 × 7,14 = 0,025 .
Natürlich hat dieses Beispiel viele Annahmen, und das Sortieren von Blasen wird selten durchgeführt. Aber die daraus resultierenden Zahlen schienen mir interessant zu sein
2) Verwenden Sie nach Möglichkeit das ereignisgesteuerte Modell der Anwendung
Der Punkt ist, dass die meisten Prozessoren mehrere "Zustände" des Stromverbrauchs unterstützen. Für den Fall, dass der Kernel nicht mit Berechnungen beschäftigt ist, versetzt ihn das Betriebssystem in einen Ruhezustand, in dem der Prozessor viel weniger Strom verbraucht.
Zustandsspektrum (Energieoptimierung):
Mehr dazu lesen Sie hier .
Sehr oft gibt es eine Situation, in der eine Anwendungslogik ausgeführt werden muss, wenn ein bestimmtes Ereignis eintritt. Um herauszufinden, dass dieses Ereignis aufgetreten ist, fragt der Dienst, der diese Informationen erhalten möchte, regelmäßig den Dienst ab, in dem die Tatsache gespeichert ist, dass dieses Ereignis abgeschlossen wurde. Mit dem Timer. Darüber hinaus erhält die überwiegende Mehrheit der Anfragen eine negative Antwort, dh 99% der Anfragen werden tatsächlich nicht benötigt.
Es wäre richtig, das entsprechende Ereignis an die Warteschlange zu senden und allen interessierten Diensten die Tatsache seines Auftretens vorzulesen.
Zustandsspektrum (Energieoptimierung):

Ein weiteres Beispiel ist das Zusammenspiel von Front-End- und Back-End-Anwendungskomponenten. Wenn die Front ihren Status abhängig von den Daten in der Datenbank ändern muss, werden manchmal regelmäßig Anforderungen an das Backend gesendet, wodurch unnötige zusätzliche Last entsteht. Es ist zwar möglich, die Front über eine Änderung des Status der erforderlichen Daten über den Socket-Server zu informieren.
Während Sockets auch falsch sein können, ist hier ein Beispiel für "schlechten" Code:
while(true)
{
// Read data
result = recv(serverSocket, buffer, bufferLen, 0);
// Handle data
if(result != 0)
{
HandleData(buffer);
}
// Sleep and repeat
Sleep(1000);
}
Es ist ersichtlich, dass der Code auch dann alle 1000 Sekunden ausgeführt wird, wenn keine Daten am Socket eingegangen sind, wodurch wertvolle Energie verschwendet wird.
Dasselbe kann auf etwas andere Weise geschrieben werden, und es wird weniger Energie verbraucht:
WSANETWORKEVENTS NetworkEvents;
WSAEVENT wsaSocketEvent;
wsaSocketEvent = WSACreateEvent();
WSAEventSelect(serverSocket,
wsaSocketEvent, FD_READ|FD_CLOSE);
while(true)
{
// Wait until data will be available in
the socket
WaitForSingleObject(wsaSocketEve
nt, INFINITE);
// Read data
result = recv(serverSocket, buffer,
bufferLen, 0);
// Handle data
if(result != 0)
{
HandleData(buffer);
}
}
3) UI/UX: «»
Wenn die Daten weiterhin verwendet werden, jedoch nur selten, ist es besser, sie nicht standardmäßig anzuzeigen, sondern nur durch Klicken auf die Schaltfläche "Detaillierte Informationen anzeigen".
Ein einfaches Beispiel, das dieses Prinzip veranschaulicht: Anzeigen von Listen von Datenobjekten (Anforderungen, Benutzer, Verkaufsstellen, Lager, Büros), vorausgesetzt, das Szenario für die Verwendung des Formulars umfasst weiterhin das Auffinden des gewünschten Objekts.
Ein Beispiel für eine schlechte Benutzeroberfläche :
Auf der Seite wird eine große Liste von Aufgaben angezeigt (unterteilt in "Seiten"), aber der Benutzer sucht weiterhin in der Suchleiste oben nach einem bestimmten Client (gemäß einer Logik in seinem Kopf). Warum Ressourcen verschwenden, um eine To-Do-Liste zu erhalten?
Das gleiche Szenario, anders implementiert:
Beispiel einer "grünen" Schnittstelle :
Die Clientauswahllogik wurde in das System verschoben. Standardmäßig werden unnötige Daten nicht "aus Gewohnheit" angefordert. Diese Option wird neben Umweltschützern und Cybersicherheit heftig begrüßt.
4) Refactoring
Refactoring ist fast immer nützlich. In diesem Zusammenhang wird es jedoch für einen einfachen Zweck benötigt: unnötigen (Müll-) Code wegzuwerfen oder den vorhandenen zu vereinfachen, um den Stromverbrauch zu senken.
Viele Anwendungen, die seit mehr als drei Jahren entwickelt werden, sammeln Hunderte von Zeilen nicht verwendeten oder unvorhersehbar funktionierenden Codes, der von zuvor implementierten (und möglicherweise bereits ausgeschnittenen) Funktionen übrig geblieben ist. Manchmal wird dieser Code sogar ausgeführt, aber das Ergebnis seiner Arbeit wird nicht beansprucht.
Durch regelmäßige Prüfung und Umgestaltung wird die Menge dieses Codes reduziert, obwohl er wahrscheinlich nicht vollständig entfernt wird.
Während wir beispielsweise einen unserer Services regelmäßig umgestalteten (innerhalb der technischen Arbeitszeitquote), stellten wir Folgendes fest:
Beispiel für ein Refactoring :
crm_deal_id- Kennung der Hypothekentransaktion im alten System. Jetzt wird es nicht mehr benötigt, aber der Code prüft immer noch, ob er es erhält, und ruft eine zusätzliche Funktion auf delete_deal_chat_telephony, die eine Reihe anderer Aktionen ausführt.
All dies kann entfernt werden, ohne die Funktionalität zu verlieren.
5) Verwenden Sie Programmiersprachen auf niedriger Ebene für Anwendungen mit hoher Last
In den meisten Fällen sind Anwendungen, die in einfachen Sprachen geschrieben sind, offensichtlich energieeffizienter. Es ist sinnvoll, einen geladenen Dienst in Python (wenn er eine einfache Operation ausführt) in C / C + neu zu schreiben. Es wird schneller und grüner.
Es stimmt, oft haben wir nicht die notwendigen Kenntnisse, um Logik in solchen Sprachen zu schreiben.
6) Gruppen-E / A-Operationen
Speichersysteme haben wie Prozessoren auch unterschiedliche Leistungszustände.
Im "Schlaf" -Modus wird viel weniger Energie verbraucht als im "warmen" Betriebszustand. Dies gilt insbesondere für Speichersysteme / Festplatten.
Wenn die Anwendung die auf die Festplatte geschriebenen Daten gruppieren und nicht ständig, sondern zu bestimmten Zeiten auf die Festplatte zugreifen kann, ist dies energieeffizienter, da das Betriebssystem die Festplatte während des Zeitraums „Leerlauf“ in den Ruhezustand versetzt.
7) Verwenden weniger stromhungriger Speichersysteme für Protokolle
Es wird empfohlen, "heißen" und "kalten" Speicher zu verwenden. Zum Beispiel ist es sinnvoll, Protokolle der letzten Woche in der indizierten Form des „heißen“ Kochens zu speichern, da die Wahrscheinlichkeit, darauf zuzugreifen, sehr hoch ist. Längere Protokolle können in billigeren und weniger stromhungrigen Speichersystemen gespeichert werden.
Wie wäre es im industriellen Maßstab?
Oben haben wir die grundlegenden Techniken für die Arbeit mit Code behandelt, um dessen Energieeffizienz sicherzustellen. Aber selbst das Befolgen der meisten dieser Regeln führt zu sehr bescheidenen Einsparungen, die schwer zu visualisieren sind. Wenn die Listen im Verkauf nicht nach der Bubble-Methode sortiert werden, wird die
gezielte Entwicklung von Funktionen für die Implementierung des elektronischen Dokumentenmanagements natürlich eine viel größere Wirkung erzielen.
Eine der Aktivitäten der Domclick-Teams besteht darin, den Prozess der Erlangung einer Hypothek zu optimieren und zu vereinfachen. Und in diesem Hypothekenprozess werden im Endstadium viele Dokumente auf Papier vorbereitet. Und in mehreren Exemplaren. Eine Kopie für den Verkäufer, eine für den Käufer, eine für die Bankakte.
Ich freue mich zu wissen, dass Domclick große Anstrengungen unternimmt, um diese bösartige Praxis zu beseitigen und den gesamten Dokumentenfluss in ein elektronisches Format zu übertragen. In diesem Jahr wurde ein erheblicher Teil der Hypothekentransaktionen bereits vollständig digitalisiert (nur ein Papier wurde gedruckt: ein Antrag auf Ausstellung eines UKEP, einer erweiterten kryptografischen elektronischen Signatur). Alle anderen Dokumente wurden von diesem UKEP unterzeichnet und es wurde kein Papier dafür ausgegeben.
Diese Initiative hat bereits über 67.491.108 Blatt Papier eingespart. In Birken gibt es ungefähr 23.000 Bäume!
Schütze die Umwelt!
Links für Interessierte:
- Green IT - verfügbare Daten und Richtlinien zur Reduzierung des Energieverbrauchs in IT-Systemen / Ardito L.; Morisio M… - In: NACHHALTIGES RECHNEN. - ISSN 2210-5379. - STAMPA
- Understanding Green Software Development: A conceptual Framework /Luca Ardito, Giuseppe Procaccianti, Marco Torchiano, Antonio Vetro
- Green SW Engineering:Ideas for including Energy Efficiency into your Softwar Projects/Gerald Kaefer