Dans les langages de programmation ayant des opérateurs de type court-circuit, ordonner les conditions à tester dans les structures conditionnelles selon leur probabilité de réalisation
Un opérateur est de type court-circuit si l’évaluation du deuxième opérande de cet opérateur peut être omise selon le résultat de l’évaluation du premier opérande (la valeur de l’opération pourrait être entièrement déterminée selon la valeur de la première condition). À l’opposé, un opérateur qui ne fait pas de court-circuit va obligatoirement évaluer ses deux opérandes pour déterminer la valeur de son opération. En C, C++, C#, Java, JavaScript ou PHP par exemple, les opérateurs logiques && (ET) et || (OU) sont de type court-circuit. Dans le cas de l’opérateur && par exemple, lorsqu’on évalue une expression du genre Expression = ConditionA && ConditionB, si ConditionA est évaluée à Faux, alors il n’est pas nécessaire d’évaluer ConditionB, et dans un tel cas Expression est évaluée à Faux. Dans le cas de l’opérateur ||, lorsqu’on évalue une expression du genre Expression = ConditionA || ConditionB, si ConditionA est évaluée à Vrai, alors il n’est pas nécessaire d’évaluer ConditionB, et dans un tel scénario Expression est évaluée à Vrai.
Compte tenu du fonctionnement spécial des opérateurs de type court-circuit et afin d’en tirer profit pour la limitation du nombre d’opérations exécutées dans un programme, et donc limiter la consommation énergétique, il convient d’écrire les opérations utilisant ces opérateurs en mettant comme premier opérande la condition la plus susceptible de provoquer le court-circuit (la non-évaluation de la deuxième opérande). Ainsi, pour utiliser l’exemple des opérateurs de type court-circuit && et || des langages C, C++, C#, Java, JavaScript ou PHP, si la condition ConditionA sera la plupart du temps évaluée à Faux en comparaison de la condition ConditionB, alors on choisira d’écrire dans le code ConditionA && ConditionB plutôt que ConditionB && ConditionA; dans ce scénario également, on choisira d’écrire ConditionB || ConditionA plutôt que ConditionA || ConditionB.
Afin d’illustrer un exemple d’implémentation en Java, considérons le cas d’une boutique en ligne qui offre des rabais de 5 % aux clients dans l’un ou l’autre des cas suivants : la date courante est un premier jour du mois ou le montant total de la commande est supérieur ou égal à 500 dollars. On suppose que statistiquement parlant, 10 % des commandes ont des montants totalisant 500 dollars ou plus. Le code ci-dessous est une première écriture d’une procédure qui calcule le rabais d’un client (on suppose que les clients sont représentés par une classe Client contenant plusieurs propriétés parmi lesquelles totalCommande qui indique le montant total de la commande en cours du client). Ce code utilise l’opérateur logique de type court-circuit || (OR), mais l’écriture n’est pas optimale.
En effet, le premier opérande de cet opérateur est l’expression calendrier.get(Calendar.DATE) == 1, et la probabilité pour que cette condition soit vraie est comprise entre 1/31 (pour les mois de l’année ayant 31 jours) et 1/28 (dans les années non bissextiles, le mois de février a 28 jours), soit environ entre 3.23% et 3.57%. D’un autre côté, selon les statistiques de la boutique en ligne, 10 % des commandes ont un montant total de 500 dollars ou plus, ce qui signifie que la probabilité pour que le deuxième opérande de l’opération logique || (la condition totalCommande >= 500) soit vrai est de 10 %. Ainsi, le deuxième opérande est environ 3 fois plus susceptible d’être vrai en comparaison du premier opérande. Par conséquent, il faut inverser l’ordre d’apparition de ces opérandes dans l’écriture de l’opérateur logique ||, comme dans le code ci-dessous, ce qui devrait permettre d’éviter plus souvent d’évaluer le deuxième opérande, calendrier.get(Calendar.DATE) == 1.
Avec cette stratégie, on devrait exécuter moins d’opérations au bout du compte, et conséquemment la consommation énergétique de l’exécution du calcul des rabais devrait être moindre que dans le cas du premier code. Cet exemple illustre comment des données statistiques d’entreprise ou d’affaires ou alors d’autres informations non techniques pourraient influencer avec pertinence la manière dont on devrait écrire un code informatique écoénergétique.
Lors de l’extraction des enregistrements des tables d’une base de données, se limiter uniquement aux champs utiles de votre application
En programmation écologique, on souhaite rationaliser ou optimiser l’utilisation des ressources de manière à minimiser la consommation énergétique des traitements, dans le but de limiter l’empreinte carbone de nos programmes. Dans le contexte de l’interrogation des données provenant d’une base de données, il faudra se montrer très prudent dans l’utilisation des requêtes SQL simples et généralistes comme la suivante :
En effet, une requête de ce genre extrait toutes les colonnes (propriétés des objets ou des entités représentées) d’une table d’enregistrements, mais très souvent la table des enregistrements contient beaucoup d’informations dont certaines peuvent ne pas du tout être pertinentes pour les besoins d’un traitement ou d’un affichage particulier. Dans le cas où la base de données se trouve sur un serveur distant n’exécutant pas directement un code informatique interrogeant la base de données, les informations inutiles et non pertinentes vont voyager sur le réseau avec les autres informations pertinentes. Non seulement ce passage par le réseau des données non pertinentes consomme inutilement de la bande passante et donc de l’énergie, mais encore de la mémoire superflue est utilisée inutilement sur le système informatique qui exécute le code d’extraction des données. Au bout du compte, les données inutiles engendrent une empreinte numérique dont il faudrait en principe se passer. Pour illustrer cette situation par un exemple, considérons une base de données d’un organisme de bienfaisance dans laquelle sont sauvegardées, dans une table nommée benevoles, des informations concernant les bénévoles ayant œuvré ou œuvrant au sein de divers départements. La structure de la table benevoles est la suivante :
benevoles(id, nom, prenom, sexe, adresse_courriel, telephone, adresse_postale, code_postal, ville, province, pays, date_embauche, nom_usager, mot_de_passe_crypte, departement, photo, disponibilite).
On suppose qu’on souhaite imprimer, à partir d’une application logicielle ou web, un rapport des bénévoles habitant la ville de Montréal et disponibles pour une activité concernant le département des affaires sociales, avec les informations de base suivantes triées par nom : le nom, le prénom, l’adresse courriel, le numéro de téléphone. Considérons la requête SQL suivante chargée d’extraire les données à imprimer :
Compte tenu du type de rapport à produire avec un nombre limité de champs d’information à afficher, cette requête SQL est très inefficace, car elle récupère beaucoup trop de données que ce qui est réellement utile, ce qui engendrerait des traitements superflus sur le serveur avec un transfert potentiel sur le réseau de certaines données inutiles. En se concentrant uniquement sur les informations pertinentes pour le rapport, on privilégiera plutôt l’utilisation de la requête suivante dans un soucis d’efficacité énergétique :
Un exemple de code pour l’exécution de cette requête SQL dans le langage Python est présenté comme suit :