L’équipe derrière le cœur d’Android, le fameux Android Runtime (ART), vient de frapper un grand coup. Elle annonce une réduction spectaculaire de 18% des temps de compilation, le tout sans sacrifier la qualité du code ni la consommation mémoire. Une prouesse technique qui va littéralement changer la donne pour des millions d’utilisateurs et de développeurs.
Un coup d’accélérateur crucial pour l’écosystème Android
Cette amélioration s’inscrit dans une initiative majeure visant à optimiser les performances d’Android d’ici 2025. L’optimisation des temps de compilation est en effet primordiale pour ART. Qu’il s’agisse de la compilation juste-à-temps (JIT), qui impacte directement la fluidité des applications et la réactivité des appareils, ou de la compilation anticipée (AOT), une exécution plus rapide se traduit par une meilleure expérience utilisateur. Moins d’attente avant que les optimisations ne prennent effet, c’est un Android plus réactif. De plus, pour les deux modes de compilation, des temps réduits signifient une consommation moindre de ressources pendant le processus, un atout majeur pour l’autonomie de la batterie et la gestion thermique, particulièrement sur les appareils d’entrée de gamme.
Ces optimisations ne sont pas une promesse lointaine. Une partie a déjà été déployée avec la mise à jour Android de juin 2025, et le reste est attendu pour la mise à jour de fin d’année. Cerise sur le gâteau, tous les utilisateurs d’Android 12 et versions ultérieures bénéficieront de ces avancées grâce aux mises à jour modulaires du système.
Optimiser l’optimisateur : le défi des compromis
Optimiser un compilateur est souvent un exercice d’équilibriste. Gagner en vitesse implique presque toujours des compromis. Cependant, l’équipe ART s’est fixé un objectif ambitieux : accélérer le compilateur sans introduire de régressions mémoire et, surtout, sans dégrader la qualité du code produit. Car, comme le soulignent les ingénieurs Santiago Aboy Solanes et Vladimír Marko :
« Si le compilateur est plus rapide mais que les applications tournent plus lentement, nous avons échoué. »
Le seul coût accepté fut celui du temps de développement, investi dans une investigation minutieuse et la recherche de solutions astucieuses répondant à ces critères stricts.
La traque aux goulets d’étranglement avec pprof
Avant d’optimiser, il faut mesurer. Heureusement, la vitesse de compilation est relativement stable sous certaines conditions (appareil constant, pas de surchauffe). Pour affiner leur diagnostic, les développeurs d’ART ont eu recours à des mesures déterministes et à des outils de profilage comme pprof. En analysant les profils de compilation d’une sélection d’applications représentatives (internes, tierces et l’OS Android lui-même), ils ont pu visualiser où le temps était le plus consommé, souvent sous forme de « flame graphs » ou de vue « bottom-up » identifiant les méthodes les plus gourmandes.
L’outil pprof a permis d’identifier des méthodes gourmandes en temps. Un exemple frappant est la méthode Kill au sein de la phase Global Value Numbering (GVN). Cette méthode, responsable à elle seule de plus de 1% du temps de compilation, itérait inutilement dans certains cas. En évitant cette itération quand la vérification est vouée à l’échec, l’équipe a pu réduire son impact de 1.023% à environ 0.3%, améliorant ainsi les performances du GVN d’environ 15%.
Des astuces de pro pour des gains concrets
L’optimisation ne se résume pas à rendre une boucle plus rapide. Parfois, il faut changer radicalement l’approche. Voici quelques-unes des techniques employées :
-
Utilisation d’heuristiques pour déterminer si une optimisation produira des résultats significatifs et peut être ignorée.
-
Ajout de structures de données supplémentaires pour mettre en cache les résultats déjà calculés.
-
Modification des structures de données existantes pour un gain de vitesse.
-
Calcul paresseux (lazy computing) des résultats pour éviter des cycles inutiles.
-
Choix de la bonne abstraction : les fonctionnalités superflues peuvent ralentir le code.
-
Éviter de suivre un pointeur fréquemment utilisé à travers de multiples chargements.
Parmi les optimisations spécifiques implémentées, on retrouve :
-
La méthode
FindReferenceInfoOfa été transformée d’une recherche linéaire (O(n)) en une opération O(1) grâce à une indexation par ID d’instruction et une pré-allocation, améliorant la phaseLoadStoreAnalysisde 34 à 66%, soit un gain de 0.5 à 1.8% sur le temps de compilation total grâce à cette modification. -
L’implémentation d’un
HashSetpersonnalisé, initialement optimisé pour de grands ensembles, a été réajustée pour des cas d’utilisation plus petits et éphémères. Résultat : une amélioration de 1.3 à 2% du temps de compilation et une réduction de la consommation mémoire de 0.5 à 1%. -
Le passage de structures de données par référence à des lambdas, évitant ainsi des copies coûteuses et offrant un gain de 0.5 à 1%.
-
L’amélioration de la phase d’écriture du code compilé via la mise en cache de valeurs calculées, qui, après une première tentative ayant entraîné une régression mémoire, a finalement permis un gain total de 1.8 à 4.6% du temps de compilation en repensant la structure.
-
Les heuristiques d’inlining ont été affinées, déplaçant des vérifications coûteuses en début de processus pour estimer la pertinence d’une inlining avant tout calcul complexe. Cette approche, sans affecter les performances, a permis des gains de 0.2 à 1.3% pour les registres DEX nécessaires et de 2% pour le nombre d’instructions.
-
Le remplacement d’une implémentation de
BitVectorparBitVectorViewpour des vecteurs de taille fixe, réduisant les indirections et les vérifications d’intervalle, et permettant des opérations plus efficaces sur les plateformes 64 bits. Ces changements, effectués au travers de plusieurs modifications du code, ont réduit les échantillons des fonctions affectées de plus de 1% lors de la compilation de l’OS Android.
Et ce n’est qu’un aperçu ! Bien d’autres astuces, de la gestion de la mémoire à la refactorisation de boucles, ont contribué à cette performance globale.
L’art d’échouer rapidement pour mieux réussir
Comme le rappellent les ingénieurs d’ART, toutes les pistes d’optimisation ne débouchent pas sur un succès. Nombreuses sont celles qui sont abandonnées faute de gains suffisants, de coûts d’implémentation trop élevés, de régressions sur d’autres métriques ou d’une complexité accrue du code. La clé est d’estimer rapidement le potentiel d’une amélioration, d’abord par intuition, puis par un prototype rapide et enfin par une implémentation complète, tout en évaluant les inconvénients potentiels comme l’utilisation de mémoire additionnelle.
Conclusion
L’engagement inébranlable de l’équipe ART à améliorer la vitesse de compilation a porté ses fruits, rendant Android plus fluide, plus efficient et optimisé pour une meilleure autonomie et gestion thermique. En identifiant et en implémentant méticuleusement ces optimisations, ils ont prouvé que des gains substantiels sont possibles sans compromettre la consommation mémoire ou la qualité du code. Ce voyage, jalonné de profilage intensif avec des outils comme pprof, d’itérations constantes et parfois d’abandons nécessaires, a posé les bases de futures avancées. Toutes ces améliorations sont disponibles via la mise à jour Android de fin d’année 2025 et, pour les versions 12 et supérieures, via les mises à jour modulaires. Une véritable masterclass en ingénierie de compilateurs !
Mots-clés : Android, ART, compilation, performances, optimisation, JIT, AOT, pprof, développeurs, Google
Source : Article original
