Autour de Java, la stratégie "green coding" d'AXA passe par le polymorphisme
AXA a entrepris d'exposer sa démarche de "green coding". Le concept de polymorphisme y a sa place, reflet d'un focus sur Java.

Green coding et polymorphisme, des approches conciliables ?
La première fait, depuis 2023, l'objet d'une communication "feuilletonnée" sur le blog IT d'AXA. Le volet initial avait traité de quelques fondements parmi lesquels la matrice de référence d'ecoCode. Ont ensuite été abordés les thèmes de la gestion durable des données, de la compilation en image native, du "développement logiciel écoresponsable" et des API.
S'y ajoute désormais le polymorphisme. Ce concept de la programmation orientée objet favorise la réutilisation de code et sa modularité en fournissant une interface unique à des entités de différents types. Des objets de classes diverses peuvent ainsi être traités comme relevant d'une superclasse commune.
Optimiser la consommation CPU...
Lorsqu'une superclasse définit une méthode, ses sous-classes peuvent ignorer cette méthode : au moment de l'exécution, la méthode appropriée est appelée en fonction du type d'objet. C'est le principe de la liaison dynamique. Il induit une certaine charge, le runtime passant par une table de méthodes virtuelles (vtable). Ces dernières peuvent par ailleurs empêcher certaines optimisations de compilateur, comme l'extension inline (remplacement d'un appel de fonction par le code de cette fonction).
Le polymorphisme est également susceptible de dégrader les performances en cas d'appels à haute fréquence - dans des boucles étroites ou sur des chemins critiques. En outre, des chaînes d'héritage complexes peuvent augmenter le temps de résolution des appels de méthodes.
Pour optimiser l'efficacité à l'exécution, la tech d'AXA recommande de :
- Préférer les interfaces aux classes abstraites
Cela encourage la composition plutôt que l'héritage, résultant souvent en des structures moins complexes. - Utiliser des classes scellées
Sur Java et Kotlin, elles limitent la hiérarchie et permettent certaines optimisations de compilateur. - Minimiser les appels polymorphiques dans les sections critiques pour la performance
On recourra plutôt à des méthodes finales ou statiques. - Combiner avec le typage statique
Cela évite les inefficacités associées à la vérification de types au moment de l'exécution.
... et mémoire
Avec ses structures d'héritage, le polymorphisme peut alourdir les en-têtes des objets (qui stockent des informations de type et des références vtable). Il peut aussi entraîner une disposition inefficace des objets (qui peuvent exiger, au sein des sous-classes, des champs supplémentaires ou du padding). De surcroît, chaque classe avec des méthodes virtuelles doit avoir sa vtable.
AXA note aussi qu'utiliser une classe de base ou un type d'interface pour les tableaux empêche d'utiliser des structures de données optimisées tels les tableaux primitifs. C'est sans compter le risque de "surutilisation" de l'héritage, au sens où on ajouterait des champs ou des méthodes redondants dans des sous-classes.
Lire aussi : AXA expose sa démarche de « green coding »
Entre autres conseils :
- Éviter les hiérarchies profondes (favoriser la composition)
- Tirer parti des structures de données compactes (collections et flux, par exemple)
- Se passer des usages non nécessaires de la polymorphie et concevoir sans spéculer sur des besoins futurs
Plus globalement, on privilégiera la réutilisation et le pooling des objets polymorphes. Et on profilera le code afin d'identifier les appels coûteux. Tout en exploitant des fonctionnalités "modernes" tels que les records de Java, qui réduisent l'usage mémoire des objets de données.
Les principes SOLID sous l'angle green coding
AXA évoque aussi les bénéfices des principes SOLID. Nous les rappelons ici brièvement :
- Responsabilité unique
Une classe ne devrait avoir qu'une seule responsabilité bien définie.
D'un point de vue green coding, cela réduit les chances de traitements non nécessaires, rendu le code plus simple à optimiser et limite potentiellement la dette technique. - Ouvert/fermé
Une classe doit être à la fois ouverte à l'extension et fermée à la modification.
Cela abaisse le coût de maintenance (plus besoin de refactoriser) et réduit les risques de problèmes de performance. - Substitution de Liskov
Un sous-type doit être sunbstituable à son type de base sans impact fonctionnel.
Cela promeut la réutilisation du code et le comportement cohérent entre classes évite les échecs inattendus. - Ségrégation des interfaces
Les clients ne devraient pas être forcés à implémenter des interfaces qu'ils n'utilisent pas.
Cela facilite la mise à jour du code, réduit les dépendances non nécessaires et occasionne moins de charge mémoire. - Inversion des dépendances
Les modules de haut niveau sont indépendants des modules de bas niveau.
Cela réduit le coût des tests de régression et facilite la maintenance.
Illustration
Sur le même thème
Voir tous les articles Green IT