- la définition de déclarations dépendantes du contexte dans Kotlin/JVM avec le prototype de récepteurs de contexte ;
- des constructions plus rapides avec la compilation parallèle d'un seul module dans le backend JVM IR ;
- un développement plus rapide grâce à la compilation incrémentale dans Kotlin/JS IR ;
- un partage de code simplifié grâce à la structure hiérarchique des projets multiplateformes ;
- des améliorations de performances de Kotlin/Native.
Prototype de récepteurs de contexte pour Kotlin/JVM
La prise en charge de plusieurs récepteurs a reçu beaucoup de votes et commentaires positifs sur l'outil de suivi de problèmes de JetBrains. Son prototypage a donc été inclus dans la feuille de route de Kotlin. JetBrains a récemment publié la proposition de conception initiale de la fonctionnalité sous le nom de récepteurs de contexte. L'éditeur de logiciels pour développeurs partage maintenant le prototype pour Kotlin/JVM.
Avec Kotlin 1.6.20-M1, vous n'êtes plus limité à un seul récepteur. Si vous avez besoin de plus, vous pouvez rendre les fonctions, les propriétés et les classes dépendantes du contexte (ou contextuelles) en ajoutant des récepteurs de contexte à leur déclaration. Une déclaration contextuelle :
- exige que tous les récepteurs de contexte déclarés soient présents dans la portée d'un appelant en tant que récepteurs implicites ;
- insère les récepteurs de contexte déclarés dans sa portée de corps en tant que récepteurs implicites.
Code : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | interface LoggingContext { val log: Logger // This context provides a reference to a logger } context(LoggingContext) fun startBusinessOperation() { // You can access the log property since LoggingContext is an implicit receiver log.info("Operation has started") } fun test(loggingContext: LoggingContext) { with(loggingContext) { // You need to have LoggingContext in a scope as an implicit receiver // to call startBusinessOperation() startBusinessOperation() } } |
Pour activer les récepteurs de contexte dans votre projet, utilisez l'option de compilateur -Xcontext-receivers. Veuillez noter que l'implémentation est un prototype :
- avec -Xcontext-receivers activé, le compilateur produira des binaires de préversion qui ne peuvent pas être utilisés dans le code de production ;
- le support EDI pour les récepteurs de contexte est actuellement minimal.
Prise en charge de la compilation parallèle d'un seul module dans le backend JVM
JetBrains poursuit son travail sur l'amélioration du temps de compilation du nouveau backend JVM IR. Dans Kotlin 1.6.20-M1, on note l'ajout en mode expérimental du backend JVM IR pour compiler tous les fichiers d'un module en parallèle. La compilation parallèle peut réduire le temps total de compilation jusqu'à 15 %.
Activez le mode backend parallèle expérimental avec l'option de compilateur -Xbackend-threads. Utilisez les arguments suivants pour cette option :
- N est égal au nombre de threads que vous souhaitez utiliser. Il ne doit pas être supérieur à votre nombre de cœurs de processeur ; sinon, la parallélisation cesse d'être efficace en raison du changement de contexte entre les threads ;
- 0 pour utiliser un thread pour chaque cœur de CPU.
Cette parallélisation n'est utile que lorsque la construction du projet n'est pas suffisamment parallélisée par un outil de build tel que Gradle. Par exemple, si vous avez un très gros module monolithique, ajouter l'option de compilateur -Xbackend-threads à ce module peut aider. Mais si un projet se compose de nombreux petits modules et a une construction parallélisée, l'ajout d'une autre couche de parallélisation peut nuire aux performances en raison du changement de contexte.
Notez que la compilation parallèle expérimentale ne fonctionne pas avec kapt car kapt désactive le backend IR. Notez également que la compilation parallèle nécessite plus de tas JVM par conception. La quantité de tas est proportionnelle au nombre de threads.
Compilation incrémentale pour les binaires de développement avec le compilateur Kotlin/JS IR
Pour rendre le développement Kotlin/JS avec le compilateur IR plus efficace, JetBrains introduit le nouveau mode de compilation incrémentielle.
Lors de la création de fichiers binaires de développement avec la tâche Gradle compileDevelopmentExecutableKotlinJs dans ce mode, le compilateur met en cache les résultats des compilations précédentes au niveau du module. Il utilise les résultats de compilation mis en cache pour les fichiers source inchangés lors des compilations suivantes, ce qui les rend plus rapides, en particulier avec de petites modifications. Notez que cette amélioration cible exclusivement le processus de développement (raccourcissement du cycle edit-build-debug) et n'affecte pas la construction des artefacts de production.
Pour activer la compilation incrémentielle pour les binaires de développement, ajoutez la ligne suivante au gradle.properties du projet :
Code : | Sélectionner tout |
kotlin.incremental.js.ir=true // false by default
Prise en charge de la structure hiérarchique pour les projets multiplateformes
Kotlin 1.6.20 arrive avec la prise en charge de la structure hiérarchique activée par défaut. Depuis son introduction dans Kotlin 1.4.0, JetBrains a considérablement amélioré la stabilité de l'interface, entre autres.
Vous pouvez désormais partager le code source entre plusieurs cibles natives similaires. La technologie fournira des dépendances par défaut correctes et trouvera l'API exacte disponible dans le code partagé. Cela élimine une configuration de build complexe et des solutions de contournement pour obtenir la prise en charge de l'EDI pour le partage des ensembles de sources entre les cibles natives. Cela aide également à empêcher les utilisations d'API non sécurisées destinées à une cible différente.
La technologie sera également utile aux auteurs de bibliothèques. Une structure de projet hiérarchique vous permet de publier et d'utiliser des bibliothèques avec des API communes pour un sous-ensemble de cibles.
Meilleur partage de code dans votre projet
Sans prise en charge de la structure hiérarchique, il n'existe aucun moyen simple de partager du code entre certaines cibles Kotlin, mais pas toutes. Un exemple particulier qui est populaire : partager du code sur toutes les cibles iOS et avoir accès à des dépendances spécifiques à iOS, comme Foundation.
Grâce à la prise en charge de la structure de projet hiérarchique, vous pouvez désormais y parvenir immédiatement. La chaîne d'outils Kotlin fournira les dépendances par défaut correctes, comme Kotlin/Native stdlib ou les bibliothèques natives.
De plus, cette technologie fera de son mieux pour trouver exactement la surface d'API disponible dans le code partagé. Cela évite des cas tels que l'utilisation d'une fonction spécifique à macOS dans le code partagé pour Windows.
Plus d'opportunités pour l'écosystème des bibliothèques
Lorsqu'une bibliothèque multiplateforme est publiée, l'API de ses sources intermédiaires est désormais correctement publiée avec elle, ce qui la rend disponible pour les consommateurs. Encore une fois, la chaîne d'outils Kotlin déterminera automatiquement l'API disponible dans l'ensemble source consommateur tout en surveillant attentivement les utilisations dangereuses, comme l'utilisation d'une API destinée à la JVM dans le code JS.
Notons également que par défaut, les bibliothèques publiées avec la structure de projet hiérarchique ne sont compatibles qu'avec les projets de structure hiérarchique.
Configuration et installation
À partir de Kotlin 1.6.20-M1, tous vos nouveaux projets multiplateformes auront une structure de projet hiérarchique. Aucune configuration supplémentaire n'est requise.
- Si vous l'avez déjà activé manuellement, vous pouvez supprimer l'option correspondante à partir de gradle.properties.
- Pour Kotlin 1.6.20, JetBrains vous recommande d'utiliser Android Studio 2021.1.1 (Bumblebee) ou version ultérieure pour obtenir la meilleure expérience.
Améliorations des performances de Kotlin/Native
JetBrains travaille sur Kotlin/Native pour accélérer le processus de compilation et améliorer votre expérience de développement.
Cette version 1.6.20 de Kotlin apporte des mises à jour de performances et des corrections de bogues qui affectent le LLVM IR généré par Kotlin. Selon les benchmarks sur des projets internes, JetBrains a réalisé en moyenne les gains de performance suivants :
- 15 % de réduction du temps d'exécution ;
- réduction de 20 % de la taille du code des binaires release et debug ;
- réduction de 26 % du temps de compilation des binaires release.
Ces modifications ont également permis de réduire de 10 % le temps de compilation d'un binaire debug sur un grand projet interne de JetBrains.
Pour y parvenir, JetBrains a implémenté une initialisation statique pour certains des objets synthétiques générés par le compilateur, amélioré la façon dont elle structure LLVM IR pour chaque fonction et optimisé les caches du compilateur.
Si vous êtes déjà passé au nouveau gestionnaire de mémoire Kotlin/Native, qui a été annoncé dans Kotlin 1.6, vous remarquerez peut-être une énorme amélioration du temps d'exécution : les benchmarks montrent une amélioration de 35 % en moyenne. Depuis cette version EAP, une implémentation concurrente de la phase de balayage est également disponible pour le nouveau gestionnaire de mémoire. Cela devrait encore améliorer les performances et réduire la durée des pauses du ramasse-miettes. Utilisez le flag -Xgc=cms pour l'activer pour le nouveau gestionnaire de mémoire Kotlin/Native.
Installer le plugin Kotlin EAP pour IntelliJ IDEA ou Android Studio