Les défis cachés du typage de Swift: Pourquoi le compilateur est-il si lent ?

Les développeurs Swift sont souvent confrontés à des temps de compilation longs, et les raisons derrière ce phénomène sont multiples. L’utilisation d’un vérificateur de types bi-directionnel Hindley-Milner (HM) explique en partie la situation. Ce vérificateur permet de maintenir une syntaxe propre et minimaliste, ce qui est idéal pour écrire du code clair et concis sans avoir à annoter explicitement chaque type. Cependant, ce luxe esthétique vient avec un coût significatif: des temps de compilation parfois extravagants, notamment pour les expressions complexes.

Un autre défi majeur évoqué par la communauté est la qualité des messages d’erreur générés par le compilateur. De nombreux développeurs se plaignent que les messages d’erreur de Swift sont souvent vagues ou difficiles à interpréter. Ceci est principalement dû au fait que le système de typage global peut propager des erreurs à travers plusieurs endroits du code, rendant leur source originelle difficile à identifier. Comme le mentionnait un utilisateur, « un bug à un endroit peut causer un échec de typage à un autre endroit complètement inattendu ». Ce phénomène rend la correction des erreurs non seulement plus lente mais aussi plus frustrante.

Pour illustrer ce problème, prenons l’exemple d’une simple ligne de code. Un utilisateur a partagé une expérience montrant qu’une ligne contenant uniquement des opérations mathématiques simples prenait plus de six secondes à être compilée dans Swift 6. Ceci est d’autant plus surprenant que dans des langages comme Python ou TypeScript, des opérations similaires s’exécuteraient presque instantanément. Voici l’exemple exact mentionné:

 let result: Double = -(1 + 1) + -(1 + 1) - 1 

image

Cette situation démontre à quel point l’inférence des types peut ajouter une surcharge considérable au processus de compilation. En comparaison, la même ligne, légèrement modifiée en Swift 5.10, peut prendre jusqu’à 11 secondes, ce qui est inacceptable pour des applications de grande envergure. Un autre exemple de variabilité des temps de compilation pour des variations minimes du même code a été donné par un utilisateur:

       let result:Double = -(1 + 1) + -(1 + 1) - 1 // 10.829s    let result:Double = -(1 + 1) + -(1 + 1)     // 1.724s    let result:Double =  (1 + 1) +  (1 + 1) - 1 // 1.721s    let result:Double = -(1 + 1)            - 1 // 0.763s    let result:Int    = -(1 + 1) + -(1 + 1) - 1 // 0.571s 

Cette variabilité est principalement due aux différents niveaux d’optimisation et aux mécanismes spécifiques utilisés par le compilateur de Swift pour typer les expressions. Swift essaie de maximiser l’inférence des types, ce qui est une bonne chose en théorie, mais en pratique, cela peut rapidement devenir un cauchemar pour les développeurs travaillant sur des projets complexes. De plus, SwiftUI, le framework de développement d’interfaces pour iOS, ajoute une couche supplémentaire de complexité au sein du système de typage, rendant les compilations encore plus lentes.

La question se pose donc: à quel point cette sophistication des systèmes de typage de Swift est-elle vraiment bénéfique ? Ne serait-il pas plus prudent de simplifier certains de ces mécanismes, comme l’ont fait d’autres langages ? Le langage de programmation Go, par exemple, est souvent cité pour sa rapidité de compilation. Une approche plus pragmatique pourrait consister à réduire certaines ambitions théoriques au profit de performances plus prévisibles et stables.

Il est également intéressant de noter que certains langages comme Haskell et OCaml, qui utilisent des systèmes de typage similaires, ne semblent pas rencontrer les mêmes problèmes. Ceci suggère que la complexité des temps de compilation dans Swift pourrait être le résultat d’autres facteurs, comme l’implémentation spécifique du compilateur ou l’interaction de ce dernier avec LLVM. Tout ceci appelle potentiellement à une réévaluation des choix techniques faits par les développeurs de Swift.


Comments

Leave a Reply

Your email address will not be published. Required fields are marked *