Comment intégrer sa programmation dans une démarche de sobriété numérique ?

Publié le 02 novembre 2022
14 minutes de lecture
Image de Lorenzo Herrera sur Unsplash

Développer un programme informatique dans une démarche de sobriété numérique nécessite d’avoir connaissance des performances de chaque langage de programmation, en termes de temps d’exécution, de mémoire mais surtout de consommation énergétique. De bonnes pratiques d’éco-conception sont également à adopter sur l’ensemble du cycle de vie de son programme, de la spécification et conception de son code jusqu’au choix du processeur.

Cet article est le premier d’une série en trois parties sur les sources de pollution numérique à intégrer dans une démarche de sobriété : d’abord la programmation informatique (fabrication du code), puis les réseaux et les datacenters et enfin l’usage des terminaux.

Quels sont les langages les plus performants ?

Une étude intitulée Energy Efficiency Across Programming Languages, menée par six chercheurs de trois universités portugaises, et présentée à Vancouver en octobre 2017 à l’occasion d’une conférence internationale sur les langages, révèle comment se comportent le temps d’exécution, l’utilisation de la mémoire et surtout la consommation et l’efficacité énergétique de 27 langages de programmation. 

Une méthode basée sur la résolution et l’exécution de 10 problèmes de programmation informatiques de référence 

L’initiative « The Computer Language Benchmarks Game » (CLBG), sur laquelle s’est basée cette étude, permettait d’obtenir un ensemble comparable et représentatif des performances d’exécution et énergétiques des programmes écrits dans 27 langages de programmation. Concrètement, comme nous pouvons le constater dans la « Table 1 » ci-dessous, le corpus du CLBG comprenait des versions de code source (les plus efficaces) liées à 13 problèmes de programmation informatiques bien connus et variés. Dans les faits, seulement 10 problèmes ont été retenus car « chameneos-redux », « meteor-contest » et « thread-ring » ne disposaient finalement pas de solutions disponibles. L’enjeu était alors de coder, d’exécuter1, tester puis comparer les solutions à chacun de ces problèmes de référence, dans et entre les différents langages. Pour opérer cette comparaison, les auteurs de l’étude se sont donc basés sur les résultats des mesures des performances d’exécution et d’efficacité énergétique de chacune des 27 solutions déployées pour chacun des 10 problèmes. Pour mettre en œuvre celles-ci, les auteurs pouvaient notamment s’appuyer sur un framework compris dans le CLBG, de sorte à ce que chacune des solutions logicielles codées respectent un algorithme donné et des directives d’implémentation spécifiques.  

Enfin, les auteurs ont suivi à la lettre les instructions du CLBG sur les versions correctes et options des compilateurs à installer pour chaque langage, avant de les tester individuellement afin de s’assurer de leur bonne exécution, sans erreur, avec une sortie conforme à ce qui était attendue. 

Une mesure de l’énergie consommée pour chaque langage via l’outil RAPL (Running Average Power Limit) 

Pour chacune des solutions compilables et exécutables dans chaque langage, des informations ont ensuite été rassemblées sur la consommation d’énergie, le temps d’exécution et l’utilisation maximale de la mémoire. Pour comparer correctement l’efficacité énergétique des langages, les auteurs ont seulement collecté, via l’outil RAPL (Running Average Power Limit) d’Intel, l’énergie consommée par une seule exécution d’une solution spécifique. Le processus global est décrit ci-dessous : 

D’ailleurs, chaque solution pour chaque problème de référence dans le CLBG a été exécutée et mesurée par chacun des langages une dizaine de fois, afin d’obtenir 10 échantillons de consommation d’énergie et de temps d’exécution. Selon les 6 chercheurs, cela permettait ainsi de réduire l’impact des démarrages à froid et des effets de cache, mais aussi d’analyser la cohérence des mesures et éviter les valeurs aberrantes. La même approche a été suivie concernant l’utilisation de la mémoire d’une solution, qui a par ailleurs été recueillie via l’outil time, disponible sur les systèmes basés sur Unix. 

Toutes les opérations réalisées (code, compilation, mesure des performances énergétiques…) pour la méthode de cette étude ont été menées sur un ordinateur de bureau avec les spécifications suivantes : Système d’exploitation Linux Ubuntu Server 16.10, noyau version 4.8.0-22-générique, avec 16 Go de RAM, un processeur Haswell Intel(R) Core(TM) i5-4460 à 3,20 GHz. Une seule architecture de processeur (Intel) multi-thread (4 coeurs) a donc été testée, ce qui peut être problématique quant à la véracité des résultats des performances obtenus dans le cadre de cette étude. Il aurait certainement fallu tester d’autres processeurs (AMD et ARM par exemple) pour ainsi avoir une représentation plus exhaustive des performances de l’ensemble des langages. On note également que les auteurs de l’étude se sont appuyés sur un seul OS (Ubuntu), probablement pour des raisons de praticité du test. Cela aurait pu être intéressant de mettre en évidence, à la place, des différenciations d’exécution selon différents OS.

Résultats des performances des langages en 2017 et 2020 

L’étude qui nous intéresse présente ci-dessous un tableau qui donne les résultats globaux (en moyenne) pour la consommation d’énergie « Energy », le temps d’exécution « Time » et la consommation maximale de la mémoire « Mb » des 27 langages de programmation en 2017, qu’ils soient compilés, interprétés en code machine ou compilés en bytecode. On peut lire par exemple que C est le langage qui consomme le moins d’énergie et que Java consomme 1,98 fois plus d’énergie que C.

De nouveaux résultats mis à jour en 2020 (tableau ci-dessous) par les mêmes chercheurs montrent une amélioration de l’efficacité énergétique de certains langages, notamment Rust (langage compilé) qui passe de 1.03 à 1.00 partageant ainsi la première place des langages les moins énergivores avec C. On découvre aussi le langage compilé Julia (1,80) qui se placerait désormais devant Java (1,98). 

Les langages interprétés Ruby et Perl qui faisaient partis des langages les plus voraces en énergie en 2017 le sont toujours en 2020, malgré une amélioration nette : 61.24 pour Ruby et 69.43 pour Perl. Ils étaient exécutés comme en 2017 via un interpréteur. On observe que Perl consommerait en 2020 moins d’énergie que le Python interprété mesuré en 2017 (75.88). Ce dernier fait en effet également parti aujourd’hui des langages les plus énergivores. Ce n’est donc pas par conséquent un des choix les plus judicieux pour développer un programme intégré dans une démarche Green IT (à moins d’adopter des bonnes pratiques d’éco-conception propres à ce langage, nous y reviendrons un peu plus tard).

Ruby et Perl sont également moins lents à l’exécution en 2020 qu’en 2017. Chose intéressante à noter pour le tableau de 2020, Julia (langage compilé) n’affiche pas un résultat, pour son temps d’exécution (3.39), équivalent ou très proche de son résultat d’efficacité énergétique (1.80), ce qui signifie qu’un langage compilé moins rapide peut quand même afficher un bon score énergétique. Enfin on retrouve Rust (langage compilé), en 2020, en haut de la pile avec le temps d’exécution le plus rapide.

Concernant le niveau d’utilisation de la mémoire (sur 2017 et 2020), c’est également Rust qui en consomme le moins avec Pascal, Go et C. Le langage Python remonte cette fois-ci dans la première moitié du classement (2.80).

La table 5 ci-dessous, publiée en 2017 dans l’étude, indiquait notamment que les langages équivalents C, Pascal et Go étaient les meilleures options pour gagner du temps, en utilisant moins de mémoire et d’énergie…

Tandis que d’autres résultats mesurés en 2020 , concernant cette même table, désignaient également Rust comme étant le meilleur langage pour gagner du temps tout en utilisant moins d’énergie et de mémoire. Il est suivi par Julia, OCaml, Lisp et Haskell.

Langages compilés, interprétés, de machine virtuelle et paradigmes de programmation : une consommation d’énergie et un temps d’exécution qui varient

Un langage compilé présente l’avantage d’être optimisé pour tel ou tel type de machine, plus précisément pour un système d’exploitation et un processeur donné. Il tourne donc beaucoup plus vite qu’un langage interprété2, non optimisé, et consomme par conséquent  moins d’énergie. Et pour preuve : les langages compilés (Julia, Haskell, OCaml, Rust, C, C++, Ada, Pascal, Chapel, Fortran, Swift, Go) consommeraient en moyenne 120 Joules pour exécuter les solutions, contre 576 Joules et 2365 Joules respectivement pour les langages de machine virtuelle (Erlang, F#, Lisp, Racket, Java, C#) et interprétés (Perl, Ruby, Dart, JavaScript, TypeScript, Hack, PHP, Lua, Jruby, Python). 

Concernant le temps d’exécution, les langages compilés prendraient en moyenne 5103 ms, contre 20 623 ms pour les langages de machine virtuelle et 87 614 ms pour les langages interprétés. 

Comme nous pouvons le constater sur les tables précédentes (2017 et 2020), les langages qui nécessitent moins d’énergie et de temps pour exécuter les solutions sont : C, Rust, C++ mais aussi Julia, OCaml et Haskell. Ces langages sont tous compilés.

Les langages les plus lents à l’exécution et qui demandent le plus d’énergie : Ruby, Perl, Python, JRuby ou encore Lua, sont tous des langages interprétés. 

Les chercheurs de l’étude Energy Efficiency Across Programming Languages ont aussi comparé différents paradigmes de programmation pour finalement conclure que les langages liés à la programmation impérative ont utilisé beaucoup moins d’énergie en moyenne, en s’exécutant beaucoup plus vite (125 J pour 5585 ms) , que des langages orientés objets (879 J pour 32 965 ms) , fonctionnels (1367 J pour 42 740 ms)  et de script (2320 J pour 88 322 ms). Leurs résultats montrent aussi que les langages impératifs n’ont besoin que de 116 Mo de mémoire, contre 249 Mo pour les langages orientés objet, 251 Mo pour les langages fonctionnels et enfin, 421 Mo pour les langages de script.

Les chercheurs ont aussi cherché à nuancer l’hypothèse selon laquelle un programme plus rapide consomme toujours moins d’énergie. Ils estiment qu’il faudrait que la puissance soit constante dans le temps pour conserver une consommation énergétique raisonnable, or cela dépend de nombreux facteurs tels que la qualité du compilateur ou encore les bibliothèques logicielles utilisées. 

Par ailleurs, selon une autre étude intitulée « Je code: les bonnes pratiques en éco-conception de service numérique à destination des développeurs de logiciels » (réalisée par Cyrille Bonamy, Cédric Boudinet, Laurent Bourgès, Karin Dassas, Laurent Lefèvre, Benjamin Ninassi et Francis Vivat3), les langages compilés seraient à privilégier pour les traitements lourds, haute performance ou temps réel. Quant aux langages interprétés, il faudrait les utiliser pour les traitements moins contraints, afin de faciliter la maintenance, le ré-usage et ainsi la durabilité. 

Après avoir étudié les performances énergétiques de 27 langages de programmation, passons désormais en revue de bonnes pratiques d’éco-conception web à adopter afin de donner à tout développeur, qui souhaite initier une démarche de sobriété numérique, une vision la plus large possible de l’ensemble des possibilités existantes.

Tour d’horizon de bonnes pratiques d’éco-conception pour intégrer son code dans une démarche Green IT

Un code peu ou très énergivore (selon le langage de programmation choisi) qui est dans les deux cas mal conçu ou trop chargé utilisera beaucoup de ressources énergétiques provenant du processeur d’un ordinateur. Ce processeur prendra en effet davantage de temps et donc d’énergie pour faire fonctionner le logiciel, ce qui conduirait par ailleurs à une autre forme de pollution numérique, à savoir le gaspillage et le remplacement du matériel si jamais la durée de vie ou la batterie de l’ordinateur est altérée. D’où la nécessité de mettre en place un certain nombre de bonnes pratiques d’éco-conception afin de produire un code qui soit le plus sobre possible en termes de consommation d’énergie. La quatrième édition de l’ouvrage Écoconception web, les 115 bonnes pratiques écrit par Frédéric Bordage, met justement en lumière certaines de ces bonnes pratiques, côté spécification et conception, sur lesquels les développeurs back comme front peuvent s’appuyer le plus tôt possible.

L’étape de spécification : Décrire le besoin des futurs utilisateurs

C’est lors de cette étape, dans le cadre de la programmation web, que les résultats en matière de réduction d’impacts environnementaux sont les plus grands. Le principe est de décrire seulement les fonctionnalités essentielles, qui ont été retenues (Minimum Viable Product), en éliminant celles qui n’étaient pas ou très peu utilisées dans la version précédente du site, s’il s’agit d’une refonte. C’est donc le rôle du product owner d’épurer la couverture et la profondeur fonctionnelle, en ne gardant que l’essentiel. Cette étape de spécification doit permettre de préciser de nombreux paramètres quantitatifs et qualitatifs comme le nombre d’items dans une liste, la qualité des images etc.

Retenir uniquement les fonctionnalités essentielles

Réduire la couverture et la profondeur fonctionnelle permet de diminuer les besoins en ressources informatiques (cycles CPU, bande passante, serveurs, etc.)  et par conséquent les impacts environnementaux. Plus l’application est sobre sur le plan fonctionnel, plus elle sera simple à utiliser. La méthode MoSCoW, des ateliers, des wireframes ou des prototypes avec tests utilisateurs sont à même de vérifier l’utilité d’une fonctionnalité en amont de son développement. Respecter le principe YAGNI (You Ain’t Gonna Need It) de l’extreme programming encourage aussi à développer seulement lorsqu’un besoin d’une fonctionnalité se fait ressentir et non lorsqu’on imagine en avoir besoin.

Quantifier précisément le besoin 

Il est nécessaire de définir précisément et dans leur ensemble les « dimensions » de chaque fonctionnalité : taux de compression pour les images, temps de réponse maximal pour une requête HTTP, nombre d’éléments dans une liste, etc. Il faut que les dimensions et exigences associées à chaque fonctionnalité correspondent en tout point au métier afin d’éviter une surqualité. Par exemple, en jouant sur le nombre d’items affichés sur la page de résultats de son moteur de recherche Bing, Microsoft Research a démontré qu’il était possible de réduire jusqu’à 80 % l’infrastructure physique sous-jacente, c’est-à-dire le nombre de serveurs. La bande passante de la plupart des utilisateurs peut aussi être réduite en utilisant par défaut une résolution de vidéo correcte (480 p) et non maximale. Les autres utilisateurs ont alors la possibilité d’augmenter cette résolution au besoin.

Supprimer les fonctionnalités non utilisées

Concrètement, cela revient à : 

  • Mesurer l’utilisation des fonctionnalités en production.
  • Piloter l’usage des fonctionnalités et supprimer celles qui ne sont pas assez utilisées, qui ne valent plus grand chose ou qui sont devenues moins pertinentes.

Supprimer des fonctionnalités obsolètes, soit en les désactivant (sur le principe du feature flipping, en empêchant qu’elles soient utilisées avec un flag) ou en les désinstallant (via une suppression maximale du code utilisé puis une refactorisation du code restant), allège le poids de l’application tout comme son impact en production et sa maintenance. Une des deux solutions de suppression est retenue en fonction du coût environnemental et économique que cela implique. 

L’étape de conception : Mise en pratique de la frugalité fonctionnelle

Lors de la conception de l’IHM4, l’interface doit être sobre, épurée, facile à comprendre et à manipuler comme le prévoit la phase de spécification, afin d’impacter le moins possible l’environnement. Product owner, futurs utilisateurs, développeurs et autres profils techniques doivent ainsi dialoguer ensemble pour réaliser le site web et l’héberger. Le but étant de privilégier l’efficience à la performance, en ne cherchant pas à aller plus vite mais à fournir une bonne expérience aux utilisateurs avec le moins de ressources possible : serveurs, bande passante, puissance du terminal utilisateur etc. Les bonnes pratiques durant cette étape doivent permettre d’épurer au maximum le futur site web, de favoriser sa modularité et de choisir une architecture (par exemple des pages web statiques ou dynamiques, une single page application, une progressive web app, etc), des technologies (solutions low tech ou high tech) et des motifs de conception (patterns) adaptés. 

La frugalité fonctionnelle côté Front

Optimiser le parcours utilisateur

Optimiser le parcours utilisateur est la priorité la plus importante durant la phase de conception. Et à raison : le temps passé par l’utilisateur sur son terminal est le deuxième poste en termes d’impacts environnementaux. Cette bonne pratique en développement web consiste à diminuer le temps passé par l’utilisateur sur ses usages qui reviennent souvent. Il s’agit alors de cibler les parcours les plus fréquents puis d’optimiser leur usage : diminuer le nombre d’étapes et d’actions (en mettant en avant par exemple les champs ou les filtres les plus utilisés) , supprimer l’inutile, identifier les cas d’échecs, optimiser les temps de réponse…Un parcours est bien conçu quand le programme se comporte exactement comme l’utilisateur l’avait imaginé. Des tests utilisateurs peuvent en effet être réalisés afin d’identifier clairement les points de friction, c’est-à-dire les situations ou interactions contribuant à dégrader l’expérience utilisateur et à ralentir leur parcours. Par exemple : Une nouvelle commande peut être proposée à un site de grande distribution sur la base du contenu de la précédente. 

N’utiliser que les portions indispensables des bibliothèques JS et CSS 

D’excellents outils existent pour concevoir rapidement des sites, comme les bibliothèques JavaScript (telles que jQuery) et les frameworks CSS (Bootstrap, Skeleton, Gumby, Foundation…) car ils répondent pratiquement à tous les besoins les plus courants. Il est cependant préférable de sélectionner des petites portions, car l’internaute risque de télécharger toute une librairie pour finalement n’utiliser qu’un faible pourcentage de ses fonctionnalités. Utiliser un bundler (par exemple Webpack)  facilite le tree shaking et l’élimination du code mort et donc inutilisé. Des frameworks proposent des bibliothèques allégées qui ne contiennent que des portions réellement utilisées par le site, réduisant ainsi le poids des fichiers téléchargés par le navigateur et les ressources consommées à l’exécution. jQuery propose par exemple une version « slim » n’incluant pas certaines fonctionnalités telles que les animations CSS et le support des échanges de données en AJAX. Résultat : une économie de 17 Ko pour la version 3.6.

Mettre en cache les données calculées souvent utilisées

Mettre en cache des calculs de valeurs ou de données souvent sollicitées et coûteux en ressources permet de générer d’importantes économies de cycles CPU. Les systèmes de cache de type key-value store, généralement montés entièrement en mémoire vive (RAM), sont prévus pour stocker ces données. Par exemple, si le nombre de produits appartenant à une catégorie est calculé alors qu’il n’est pas mis à jour de manière très fréquente, il convient alors de le mettre en cache afin de gagner du cycle CPU. Les jetons d’accès en OAuth2 sont associés à une date d’expiration. Le fait de mettre en cache le jeton et son délai d’expiration permet d’éviter des appels inutiles au serveur d’autorisation et de devoir revalider le jeton. 

La frugalité fonctionnelle côté Back

Limiter le nombre d’appels aux API HTTP

Chaque affichage de page web consultée par un internaute engendre autant de requêtes HTTP vers différentes API alors que le contenu sera probablement le même durant un certain temps. D’un côté, un fournisseur d’API (serveur) a donc la possibilité de fixer des quotas pour inciter les utilisateurs à définir une stratégie de mise en cache des réponses et éviter des appels systématiques aux API HTTP (webservice). De l’autre, l’utilisateur d’API (client) doit mettre en cache les résultats obtenus afin de pouvoir les proposer à nouveau sans appeler en permanence l’API HTTP. Quelques exemples : S’il est possible de récupérer des avis clients via une API, il est alors probable de limiter le nombre de requêtes à une par jour. Même chose pour la récupération d’un flux Twitter qui est affiché sur un site, il est probable de limiter le nombre de requêtes à une par heure. Enfin, une donnée affichée en temps réel sur la page d’accueil d’un site peut donner lieu à sa mise en cache durant 2 secondes afin d’éviter que des milliers de visiteurs simultanés sur ledit site génèrent des milliers d’appels d’API durant la même seconde.

Réduire le volume de données stockées au strict nécessaire

Cette bonne pratique revient à :

  • Optimiser la gestion des gros volumes de données ;
  • Nettoyer les anciennes données, en les archivant hors ligne ou en les supprimant ;
  • Vérifier que les sauvegardes peuvent être restaurées ; 
  • Superviser la taille des espaces de stockage.

Il faut prendre en compte que des contraintes légales peuvent amener à stocker dans le temps des données jamais utilisées. L’utilisation des données et leur degré d’importance impactent également la manière de les stocker. 

Comme mesures concrètes, il est possible de définir les processus d’archivage : un rapport annuel peut être être stocké sur un SSD (zone chaude) au moment de sa sortie, puis archivé sur un stockage classique (zone froide) un mois plus tard, avant d’être supprimé dix ans plus tard. Éviter les doublons entre les tables optimiserait aussi concrètement le volume de données stockées.

Ne se connecter à une base de données que si nécessaire

Processus coûteux en ressources pour le client et le serveur, l’ouverture d’une connexion (quel que soit le système de base de données) implique : 

  • Une allocation de mémoire et un accès disque pour les buffers ;
  • Des allers-retours réseaux pour le protocole de connexion ; 
  • Un coût CPU induit.

Comme bonne pratique, un pool de connexion JDBC  (tel que HikariCP, intégré dans SpringBoot, par exemple) peut être mis en place étant donné qu’il permet d’optimiser la gestion des connexions et les performances. À noter que la configuration d’un pool de connexion nécessite de superviser le comportement de celui-ci pour trouver le bon paramétrage. Lorsque l’installation d’un pool de connexion n’est pas possible, il est conseillé de réutiliser une connexion et de ne pas ouvrir / fermer une nouvelle connexion à chaque requête.

Mettre en place une architecture élastique 

La nuit, il n’y a souvent que peu ou pas du tout d’utilisateurs connectés. Il n’est pas nécessaire dans ce cas d’utiliser des infrastructures techniques aussi importantes aux heures creuses qu’aux heures de plus forte demande. Installer une architecture élastique déclenche alors des économies puisque moins de ressources serveurs sont utilisées et facturées. Par exemple : Mutualiser des déploiements sur le cloud peut modifier automatiquement la taille de l’infrastructure, en fonction d’une programmation horaire ou d’un nombre de requêtes. 

Pour aller plus loin, Product Owner comme développeurs back ou front ont la possibilité d’accéder et de contribuer librement à un dépôt du référentiel Écoconception web, les 115 bonnes pratiques sur GitHub. Un référentiel général d’écoconception de services numériques (RGESN), ainsi qu’un guide de référence pour écoconcevoir des services numériques réalisé par l’AFNOR, précisent également certaines bonnes pratiques à mettre en oeuvre afin d’intégrer son code dans une démarche de sobriété numérique.

Intégrer son code dans une démarche d’éco-conception passe aussi par un choix rigoureux du processeur

L’étude Impact des langages de programmation sur la performance énergétique des applications de calcul scientifique : un challenge ? , publiée en Mai 2022, nous éclaire sur l’impact du choix lié au processeur (composant électronique essentiel pour exécuter un programme) sur la réussite ou non de la démarche d’éco-conception initiée dès les étapes de spécification et de conception d’un programme. Un processeur vieillissant en termes de performances, concernant le temps d’exécution ou l’efficacité énergétique, peut en effet réduire à néant de bonnes pratiques d’éco-conception du code mises en place, comme celles détaillées ci-dessus. D’où l’intérêt de choisir rigoureusement son processeur pour tel type de  programme élaboré avec tel type de langage.

Les deux tableaux suivants dans l’étude illustrent les temps d’exécution et énergies consommées de 6 processeurs différents, en mode mono-thread (un seul cœur) puis en mode multi-thread (plusieurs cœurs), testés avec les langages C, Fortran, Java, Julia, Py-Numba, Go, et Rust.

On observe notamment que les résultats en termes de temps d’exécution et d’énergie consommée sont bien meilleurs lorsque ces processeurs sont utilisés en mode multi-thread d’où l’intérêt de ne garder que ce mode afin de conserver les efforts réalisés au préalable, lors de la programmation, en matière de bonnes pratiques d’éco-conception. Si l’on regarde plus précisément les résultats par langage pour ce mode-ci, on constate que le serveur bi-processeur ARM X2 99xx (64C) est réellement efficace quel que soit le langage considéré, contrairement au serveur bi-processeur AMD Opteron 250 (2C), qui n’est pas performant sur l’ensemble des langages.

Sources

  • Écoconception web, les 115 bonnes pratiques – Doper son site et réduire son empreinte écologique. 4 ème édition, Éditions Eyrolles, 2019, 2022. Frédéric Bordage. 

1 Un programme que l’on appelle selon les cas un compilateur ou un interpréteur se charge de transformer notre code source en un fichier exécutable, généralement unique, afin que notre programme puisse fonctionner. Il existe deux types de fichiers exécutables : les bibliothèques logicielles et les logiciels en eux-mêmes. 

2 Les interpréteurs optimisent moins le code machine qu’ils génèrent, ce qui les rend plus lents à l’exécution, mais le processus de génération du code machine est de fait plus rapide que celui des compilateurs. 

3 Les auteurs sont membres du Groupement de Service CNRS EcoInfo qui travaille sur l’écoresponsabilité du numérique.

4 IHM signifie interface homme-machine et fait référence à un tableau de bord qui permet à un utilisateur de communiquer avec une machine, un programme informatique ou un système.