Microsoft annonce .NET 7 Preview 3, la version du framework pour la création des applications,
apporte une amélioration du temps de démarrage avec la fonction Write-Xor-Execute activée de 10 à 15 %

Microsoft a annoncé en début d’année la disponibilité de la Preview 1 de .NET 7. Plus tôt le 13 de ce mois, Jon Douglas, Directeur de programme senior, NuGet, annonce la sortie de .NET 7 Preview 3. « Aujourd'hui, nous sommes heureux de publier l'aperçu 3 de .NET 7. La Preview 3 de .NET 7 comprend des améliorations de l'observabilité, des temps de démarrage, du codegen, des régions GC, de la compilation AOT native, et bien plus encore », déclare Jon Douglas sur le blog de Microsoft.

« .NET 7 s'appuie sur la base établie par .NET 6, qui comprend un ensemble unifié de bibliothèques de base, de runtime et de SDK, une expérience de développement simplifiée et une productivité accrue des développeurs. Les principaux domaines d'intérêt de .NET 7 comprennent une meilleure prise en en charge des scénarios cloud native, des outils facilitant la mise à niveau des projets existants et la simplification de l'expérience du développeur en facilitant le travail avec les conteneurs », a écrit Jeremy Likness de l'équipe .NET à propos de cette version. En gros, .NET 7 vise à faciliter le développement d'applications cloud natives et la conteneurisation.

Voici, ci-dessous, les nouvelles fonctionnalités qu’apporte la Preview 3 de .NET 7

Des applications plus rapides et plus légères avec Native AOT

Dans le billet de blog de Preview 3 de .NET 7, Microsoft a annoncé que le projet Native AOT avait quitté son statut expérimental pour passer en développement principal dans .NET 7 dans le repo dotnet/runtime. « Nous savons que beaucoup d'entre vous attendaient avec impatience des mises à jour de l'équipe sur ce qui allait arriver à Native AOT, et nous avons quelques nouvelles mises à jour pour la Preview 3 », déclare Microsoft.

Qu'est-ce que Native AOT ?

La compilation Ahead-of-time (AOT) désigne un ensemble de technologies qui génèrent du code au moment de la construction de l'application, au lieu de l'exécuter. L'AOT n'est pas nouveau pour .NET. Aujourd'hui, fourni ReadyToRun pour les scénarios client et serveur, et Mono AOT pour les applications mobiles et WASM. Native AOT apporte une précompilation native complète aux scénarios client et serveur du bureau .NET. Native AOT ne remplace pas ces technologies existantes, mais offre plutôt un nouvel ensemble de capacités qui débloquent de nouveaux facteurs de forme.

Les assemblages .NET existants compilés par AOT contiennent des structures de données et du code natif spécifiques à la plate-forme, qui permettent de concentrer le travail habituellement effectué au moment de l'exécution. La précompilation de ces artefacts permet de gagner du temps au démarrage (p. ex. ReadyToRun) et d'accéder aux plateformes no-JIT (p. ex. iOS). Si les artefacts précompilés ne sont pas présents, .NET revient à la JIT ou à l'interprétation (selon la plate-forme).

Native AOT est similaire aux technologies AOT existantes de .NET, mais il ne produit que des artefacts natifs. En fait, le moteur d'exécution Native AOT ne sait pas comment lire les formats de fichiers d'assemblage .NET - tout est natif de la plate-forme. L'analyse du format du fichier exécutable est entièrement gérée par le système d'exploitation sous-jacent.

Le principal avantage de Native AOT réside dans le temps de démarrage, l'utilisation de la mémoire, l'accès aux plateformes restreintes (pas de JIT autorisé) et la taille réduite sur le disque. Les applications commencent à s'exécuter au moment où le système d'exploitation les place en mémoire. Les structures de données sont optimisées pour l'exécution du code généré par l'AOT, et non pour la compilation d'un nouveau code au moment de l'exécution.

Cela ressemble à la façon dont des langages comme Go, Swift et Rust compilent. Native AOT convient le mieux aux environnements où le temps de démarrage est le plus important. Le ciblage de Native AOT a des exigences plus strictes que les applications et bibliothèques générales de .NET Core/5+. Native AOT interdit l'émission de nouveau code à l'exécution (par exemple, Reflection.Emit) et le chargement de nouveaux assemblages .NET à l'exécution (par exemple, les modèles de plug-in).

Native AOT et les applications

Pour .NET 7, Microsoft cible les applications console et les bibliothèques natives comme scénario principal pour Native AOT. Les développeurs d'applications et les auteurs de bibliothèques peuvent désormais tirer parti de Native AOT en s'assurant que leurs applications sont ajustables. Étant donné que l'ajustement est une condition préalable à la compilation de Native AOT, préparer les applications et bibliothèques à l'ajustement aidera à se préparer à Native AOT. « Si vous êtes l'auteur d'une bibliothèque .NET, le fait de suivre les instructions "Trimming libraries" vous aidera à préparer vos bibliothèques pour le trimming et Native AOT », indique Microsoft.

L'une des applications que Microsoft prévoit d'expédier dans .NET 7 compilé avec Native AOT est l'outil crossgen. Crossgen fait partie du SDK .NET. Il s'agit du compilateur CoreCLR AOT qui produit des exécutables ReadyToRun. Crossgen est écrit en C# et nous l'expédions actuellement compilé avec lui-même comme une application ReadyToRun (c'est des tortues tout le long du chemin !). « Nous voyons déjà des chiffres très prometteurs en termes de vitesse de compilation et de taille », indique Microsoft. Crossgen bénéficie largement de l'AOT natif parce que c'est un processus de courte durée et que l'overhead de démarrage domine le temps d'exécution global :

Nom : sce.png
Affichages : 30091
Taille : 15,5 Ko

Pour l'avenir, la compatibilité avec Native AOT sera améliorée au cours des prochaines versions de .NET, mais il y aura toujours des raisons de préférer JIT pour de nombreux scénarios. Microsoft annonce également un support de premier ordre dans le SDK dotnet pour la publication de projets avec Native AOT.

Observabilité

.NET 7 continue de faire évoluer la prise en charge de la spécification OpenTelemetry native du cloud. La Preview 3 ajoute le support des mises à jour de la spécification #988 et #1708 qui rendent l'état de la trace mutable pour les échantillonneurs.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
//  ActivityListener Sampling callback
    listener.Sample = (ref ActivityCreationOptions<ActivityContext> activityOptions) =>
    {
        activityOptions = activityOptions with { TraceState = "rojo=00f067aa0ba902b7" };
        return ActivitySamplingResult.AllDataAndRecorded;
    };

System.Composition.Hosting

La dernière version du Managed Extensibility Framework bénéficie d'une légère mise à jour pour s'aligner sur les API de la version précédente. Les nouvelles API permettent d'ajouter une seule instance d'objet au conteneur System.Composition.Hosting. Semblable à la fonctionnalité fournie dans les interfaces héritées System.ComponentModel.Composition.Hosting avec l'API ComposeExportedValue(CompositionContainer, T).

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
namespace System.Composition.Hosting
{
    public class ContainerConfiguration
    {
        public ContainerConfiguration WithExport<TExport>(TExport exportedInstance);
        public ContainerConfiguration WithExport<TExport>(TExport exportedInstance, string contractName = null, IDictionary<string, object> metadata = null);
 
        public ContainerConfiguration WithExport(Type contractType, object exportedInstance);
        public ContainerConfiguration WithExport(Type contractType, object exportedInstance, string contractName = null, IDictionary<string, object> metadata = null);
    }
}

Amélioration du temps de démarrage avec Write-Xor-Execute activé

Les performances continuent d'être une préoccupation majeure pour .NET 7. Le PR dotnet/runtime#65738 a réimplémenté les stubs de comptage de précodes et d'appels (stubs d'aide à la compilation à plusieurs niveaux) afin de réduire de manière significative le nombre de modifications post-création du code exécutable dans le runtime. Cela a permis d'améliorer le temps de démarrage de 10 à 15 %.

En prime, cette modification a également permis d'améliorer les performances en régime permanent (jusqu'à 8 %) dans certains microbenchmarks et certains benchmarks ASPNet, même si l'option Write-Xor-Execute n'est pas activée. Cependant, il y a quelques régressions résultant de ce changement aussi (sans Write-Xor-Execute activé) qui seront traitées dans les prochaines versions préliminaires. Elles ont été observées dans les benchmarks Orchard et Fortunes sur les processeurs Intel uniquement.

CodeGen

Grâce en grande partie aux contributeurs de la communauté, la Preview 3 présente plusieurs optimisations et corrections de bogues pour la génération de code et la compilation juste-à-temps (JIT). Voici un aperçu de quelques changements qui sont disponibles aujourd'hui.

Optimisations des boucles

Le clonage de boucle a amélioré la durée de l'invocation unique de 21 % pour System.Collections.Tests.Perf_BitArray.BitArrayLeftShift(Size : 512) :

Nom : sys.png
Affichages : 1490
Taille : 71,7 Ko

Cryptographie : Génération de noms X.500 plus robuste

Cette modification simplifie le travail avec les certificats en introduisant une classe qui fournit plus de clarté pour l'analyse des noms X.500. Rend plus sûr et plus facile la construction d'un X500DistinguishedName. Classiquement, toute personne souhaitant construire un nom X.500 (comme pour la création de certificats de test avec la classe CertificateRequest) le faisait en manipulant des chaînes de caractères, soit par le biais d'un simple littéral, soit par le biais d'un formatage de chaîne de caractères, par ex.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
request = new CertificateRequest($"CN={subjectName},OU=Test,O=""Fabrikam, Inc.""", ...);
Cela convient généralement, sauf lorsque subjectName contient une virgule, une citation ou tout autre élément qui a une influence sur l'analyseur syntaxique. Pour résoudre ce problème, nous avons ajouté la classe X500DistinguishedNameBuilder. Comme chaque méthode n'opère que sur un seul nom distinctif relatif (RDN), il n'y a aucune ambiguïté dans l'analyse syntaxique. En prime, comme les identificateurs RDN sont développés, vous n'avez plus à deviner la signification de "CN" ("Common Name").

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
X500DistinguishedNameBuilder nameBuilder = new();
nameBuilder.AddCommonName(subjectName);
nameBuilder.AddOrganizationalUnitName("Test");
nameBuilder.AddOrganizationName("Fabrikam, Inc.");

Code : Sélectionner tout - Visualiser dans une fenêtre à part
request = new CertificateRequest(nameBuilder.Build(), ...);
Régions GC activées par défaut

Avec la Preview 3, la fonctionnalité des régions qui devrait aider à l'utilisation de la mémoire pour les applications à haut débit a été activée par défaut. La fonctionnalité est maintenant activée pour toutes les plateformes à l'exception de MacOS et NativeAOT (qui seront activés dans le futur). Microsoft prévoit une augmentation du nombre de jeux de travail pour les petites applications en raison de la façon dont les régions sont initialement allouées.

Source : Microsoft

Et vous ?

Que pensez-vous des changements et des nouveautés introduits par la Preview 3 de .NET 7 ?

Voir aussi :

Microsoft publie le premier aperçu de .NET 7 avec des optimisations continues du compilateur JIT, de nouvelles API et la prise en charge de plus de scénarios de rechargement à chaud

Microsoft annonce .NET 6 Preview 5, la version du framework pour la création des applications, apporte une amélioration des charges de travail

Visual Studio 2022 64-bit Preview 2 est disponible, elle apporte de nouvelles fonctionnalités et permet de créer des applications multiplateformes

.NET MAUI Release Candidate est Prêt pour le développement d'applications multiplateformes, elle s'appuie sur les SDK de plateforme pour Android, iOS, macOS et Windows