Bonjour. Je m'appelle Stas, chez Domclick, je supervise le développement des services de back-office pour les prêts hypothécaires chez Sberbank.
Récemment, dans toutes sortes de rapports et de podcasts, j'ai souvent rencontré le terme «code vert». Après avoir fouillé sur Internet et étudié ce sujet, je me suis rendu compte que ce terme décrit un ensemble de techniques de développement et de conception d'applications qui peuvent réduire la consommation d'énergie de l'équipement sur lequel ce code est exécuté.
Plus ou moins cette question est généralement déconcertée par les développeurs d'applications mobiles, principalement parce que l'appareil sur lequel leur code sera exécuté a une capacité de batterie limitée.
Le sujet est devenu assez "hype", et j'ai décidé de comprendre comment exactement les principes du "vert" peuvent être reflétés dans le développement WEB.
Principes de base de l'écriture du "code vert"
Après avoir lu de nombreux rapports et articles sur ce sujet, je voudrais souligner les aspects suivants du développement d'applications qui affectent la consommation d'énergie:
1) Simplification et optimisation des algorithmes
Comme mentionné ci-dessus, l'exécution du code devrait conduire à une consommation d'énergie minimale. Le code optimisé s'exécutera plus rapidement et, par conséquent, nécessitera moins de coûts de traitement et de refroidissement de l'équipement.
Essayons de calculer la différence de consommation d'énergie pour exécuter une opération spécifique dans le code - le tri classique d'une liste. J'exagérerai délibérément la situation dans l'exemple donné afin de montrer la différence de contraste.
Prenons une sorte de bulle. C'est probablement l'un des moyens les moins optimaux. Cela nous convient très bien. Calculons le tri de la liste et voyons comment cela a affecté la consommation d'énergie du MacBook. Tout d'abord, simulons le tableau de données et la logique de tri des bulles elle-même:
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)
Pour mesurer l'impact de l'exécution de code sur la consommation d'énergie, j'ai utilisé le système de surveillance iStat Menus 6 (https://bjango.com/mac/istatmenus/). J'ai connecté mon MacBook au réseau, fermé toutes les applications tierces, attendu un certain temps pour charger la batterie et commencé le tri: Graphique de consommation électrique
lors du tri à bulles:
Un saut prononcé de consommation électrique d'une durée de 305 secondes est visible. Cela a été causé par l'exécution de notre demande non optimale. De plus, l'énergie dépensée pendant 5 minutes (305 secondes)
P = (W2 – W1) × 305 = (17,29 [ ] – 2,9 [ ]) × 305 = 14,39 × 305 = 4389 = 0,0012 *
.
Maintenant, disons que ce code est accidentellement arrivé à un serveur de produit industriel (supposons que la consommation d'énergie supplémentaire sur le serveur sera la même que sur mon MacBook et que la dépendance est directement proportionnelle) et a commencé à être exécuté avec une fréquence de 1 toutes les 10 secondes. Puis un an , nous obtenons plus d' énergie:
365 × 24 × 3600 /10 × 0,0012 * = 3 784,32 *
.
Supposons que le centre de données hébergeant le serveur soit alimenté par une chaufferie qui utilise le bois de bouleau comme combustible. Lors de la combustion de 1 m 3 de bois de bouleau, 1900 kW * h / m 3 d' énergie sont libérés. Bien sûr, l'efficacité de la chaudière est pas à 100%, et si l' on prend pour 75%, nous obtenons: . Si nous prenons un arbre comme un cylindre régulier, dont le volume est
(3 784,32 / 1900) / 0,75 = 2,66 3
V = Pi × R2 × H
où R est le rayon du tronc d'arbre, prenons-le à 0,12 mètre (valeur moyenne),
H est la hauteur du tronc d'arbre, prenons-le à 3 mètres (valeur moyenne).
alors nous obtenons: Cela signifie qu'il y aura du bois dans un mètre cube . Nous avons besoin d'un an pour alimenter notre scénario . À titre de comparaison, j'ai effectué le même tri en utilisant la méthode de tri standard Python ( ). Graphique de consommation d'énergie lors d'un tri standard en Python: En appliquant la même logique de calcul (la durée du pic était de 10 secondes), on obtient: En un an, on obtient (à condition que l'opération soit effectuée 1 fois en 10 secondes) Ou:
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 .
Bien sûr, cet exemple comporte de nombreuses hypothèses et le tri à bulles est rarement effectué. Mais les chiffres qui en résultent m'ont semblé intéressants
2) Utilisez le modèle événementiel de l'application dans la mesure du possible
Le fait est que la plupart des processeurs prennent en charge plusieurs «états» de consommation d'énergie. Dans le cas où le noyau n'est pas occupé par des calculs, le système d'exploitation le met dans un état «veille», dans lequel le processeur consomme beaucoup moins d'énergie.
Spectre d'états (optimisation énergétique):
pour en savoir plus, cliquez ici .
Très souvent, il y a une situation où une logique d'application doit être exécutée lorsqu'un certain événement se produit. Et pour savoir que cet événement s'est produit, le service intéressé à recevoir ces informations interroge souvent périodiquement le service qui stocke le fait que cet événement est terminé. Par minuterie. De plus, l'écrasante majorité des demandes reçoivent une réponse négative, c'est-à-dire que 99% des demandes ne sont en fait pas nécessaires.
Il serait correct de diffuser l'événement correspondant dans la file d'attente et de lire le fait de son occurrence à tous les services intéressés.
Spectre d'états (optimisation énergétique):
Un autre exemple est l'interaction des composants d'application frontaux et principaux. Si le front doit changer son état en fonction des données de la base de données, des demandes sont parfois envoyées périodiquement au backend, créant une charge supplémentaire inutile. Bien qu'il soit possible d'informer le front d'un changement dans l'état des données nécessaires via le serveur de socket.
Bien que les sockets puissent également être erronés, voici un exemple de "mauvais" code:
while(true)
{
// Read data
result = recv(serverSocket, buffer, bufferLen, 0);
// Handle data
if(result != 0)
{
HandleData(buffer);
}
// Sleep and repeat
Sleep(1000);
}
On peut voir que même si aucune donnée n'est arrivée sur la prise, le code sera toujours exécuté toutes les 1000 secondes, gaspillant une énergie précieuse.
La même chose peut être écrite d'une manière légèrement différente, et moins d'énergie sera dépensée:
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: «»
Si les données sont encore utilisées, mais rarement, il est préférable de ne pas les afficher par défaut, mais de les afficher uniquement en cliquant sur le bouton "Afficher les informations détaillées".
Un exemple simple illustrant ce principe: afficher des listes d'objets de données (demandes, utilisateurs, points de vente, entrepôts, bureaux), à condition que le scénario d'utilisation du formulaire implique toujours de trouver l'objet souhaité.
Un exemple de mauvaise interface :
La page affiche une énorme liste de tâches (divisée en "pages"), mais l'utilisateur cherchera toujours un client spécifique (selon une logique dans sa tête) dans la barre de recherche en haut. Pourquoi gaspiller des ressources pour obtenir une liste de choses à faire?
Le même scénario, implémenté de manière différente:
Exemple d'interface "verte" :
La logique de sélection du client a été déplacée vers le système, par défaut, les données inutiles ne sont pas demandées «par habitude». Cette option, en plus des écologistes, et la cybersécurité seront vivement applaudies.
4) Refactoring
Le refactoring est presque toujours utile. Mais dans ce contexte, il est nécessaire dans un seul but: jeter du code inutile (garbage) ou simplifier l'existant pour réduire la consommation d'énergie.
De nombreuses applications qui se développent depuis plus de trois ans accumulent des centaines de lignes de code inutilisé ou fonctionnant de manière imprévisible, laissées par des fonctions précédemment implémentées (et peut-être déjà coupées). Parfois, ce code est même exécuté, mais le résultat de son travail n'est pas requis.
Un audit et une refactorisation périodiques réduiront la quantité de ce code, même s'ils ne s'en débarrasseront probablement pas complètement.
Par exemple, en refactorisant régulièrement l'un de nos services (dans le cadre du quota technique d'heures de travail), nous avons trouvé ceci:
Exemple de refactoring :
crm_deal_id
- identifiant de la transaction hypothécaire dans l'ancien système. Maintenant, il n'est plus nécessaire, mais le code vérifie toujours pour l'obtenir et appelle une fonction supplémentaire delete_deal_chat_telephony
qui effectue beaucoup d'autres actions.
Tout cela peut être supprimé sans perte de fonctionnalité.
5) Utilisez des langages de programmation de bas niveau pour les applications à forte charge
De toute évidence, dans la plupart des cas, les applications écrites dans des langages de bas niveau sont plus économes en énergie. Il est logique de réécrire un service chargé en Python (s'il effectue une opération simple) en C / C +. Ce sera plus rapide et plus vert.
Certes, nous n'avons souvent pas les connaissances nécessaires pour écrire la logique dans de tels langages.
6) Opérations d'E / S de groupe
Les systèmes de stockage, comme les processeurs, ont également des états d'alimentation différents.
En mode «veille», beaucoup moins d'énergie est consommée que dans un état de fonctionnement «chaud». Cela est particulièrement vrai pour les systèmes de stockage / disques durs.
Si l'application peut regrouper les données écrites sur le disque et accéder au disque non pas constamment, mais à certaines périodes de temps, alors ce sera plus économe en énergie, car pendant la période «d'inactivité», le système d'exploitation enverra le disque en «hibernation».
7) Utilisation de systèmes de stockage moins gourmands en énergie pour les journaux
Il est recommandé d'utiliser le stockage «chaud» et «froid». Par exemple, il est judicieux de stocker les journaux de la semaine dernière sous la forme indexée de cuisson «chaude», car la probabilité d'y accéder sera assez élevée. Les bûches plus longues peuvent être stockées dans des systèmes de stockage moins chers et moins gourmands en énergie.
Que diriez-vous à l'échelle industrielle?
Ci-dessus, nous avons couvert les techniques de base pour travailler avec le code pour garantir son efficacité énergétique. Mais même en suivant la plupart de ces règles, des économies très modestes seront difficiles à visualiser. Bien sûr, si les listes ne sont pas triées par la méthode de la bulle dans les ventes, le
développement ciblé de fonctionnalités pour la mise en œuvre de la gestion électronique des documents donnera un effet beaucoup plus grand.
L'une des activités des équipes Domclick est d'optimiser et de simplifier le processus d'obtention d'un crédit immobilier. Et dans ce processus hypothécaire, au stade final, de nombreux documents sont préparés sur papier. Et en plusieurs exemplaires. Un exemplaire pour le vendeur, un pour l'acheteur, un pour le dossier bancaire.
Je suis heureux de savoir que Domclick consacre beaucoup d’efforts à éliminer cette pratique vicieuse et à transférer l’ensemble du flux de documents au format électronique. Cette année, une part importante des transactions hypothécaires a déjà été entièrement numérisée (un seul papier a été imprimé: une demande d'émission d'un UKEP, une signature électronique cryptographique améliorée). Tous les autres documents ont été signés par cet UKEP et aucun papier n'a été dépensé pour eux.
Cette initiative a déjà permis d'économiser plus de 67 491 108 feuilles de papier. Chez les bouleaux, il y a environ 23 000 arbres!
Protéger l'environnement!
Liens pour les personnes intéressées:
- Green IT - données disponibles et directives pour réduire la consommation d'énergie dans les systèmes informatiques / Ardito L.; Morisio M… - Dans: INFORMATIQUE DURABLE. - 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