Réflexion et génération de source dans System.Text.Json
Cet article explique les différences entre la réflexion et la génération de source en ce qui concerne la sérialisation System.Text.Json
. Il fournit également des conseils sur la façon de choisir la meilleure approche pour votre scénario.
Collection de métadonnées
Pour sérialiser ou désérialiser un type, JsonSerializer a besoin d’informations sur la façon d’accéder aux membres du type. JsonSerializer
a besoin des informations suivantes :
- Comment accéder aux getters de propriétés et aux champs pour la sérialisation.
- Comment accéder à un constructeur, à des setters de propriétés et à des champs pour la désérialisation.
- Informations sur les attributs utilisés pour personnaliser la sérialisation ou la désérialisation.
- Configuration au moment de l’exécution à partir de JsonSerializerOptions.
Ces informations sont appelées métadonnées.
Réflexion
Par défaut, JsonSerializer collecte les métadonnées au moment de l’exécution à l’aide de la réflexion. Chaque fois que JsonSerializer
doit sérialiser ou désérialiser un type pour la première fois, il collecte et met en cache ces métadonnées. Le processus de collecte de métadonnées prend du temps et utilise de la mémoire.
Génération de la source
En guise d’alternative, System.Text.Json
peut utiliser la fonctionnalité de génération de source C# pour améliorer les performances, réduire l’utilisation de la mémoire privée et faciliter le découpage d’assembly, ce qui réduit la taille de l’application. En outre, certaines API de réflexion ne peuvent pas être utilisées dans des applications AOA natives. Vous devez donc utiliser la génération de source pour ces applications.
La génération de source peut être utilisée dans deux modes :
Mode basé sur les métadonnées
Lors de la compilation,
System.Text.Json
collecte les informations nécessaires à la sérialisation et génère des fichiers de code source qui remplissent les métadonnées de contrat JSON pour les types demandés.Mode d’optimisation de la sérialisation (chemin rapide)
Les fonctionnalités JsonSerializer qui personnalisent la sortie de la sérialisation, comme les stratégies d’affectation de noms et la conservation des références, implique des coûts en performance. En mode d’optimisation de la sérialisation, System.Text.Json génère un code de sérialisation optimisé qui utilise
Utf8JsonWriter
directement. Ce code optimisé ou à chemin rapide augmente le débit de sérialisation.La désérialisation à chemin rapide n’est actuellement pas disponible. Pour obtenir plus d’informations, consultez Problème dotnet/runtime 55043.
La génération de source pour System.Text.Json
nécessite C# 9.0 ou une version ultérieure.
Comparaison des fonctionnalités
Choisissez des modes de réflexion ou de génération de source en fonction des avantages suivants offerts par chacun d’eux :
Avantage | Réflexion | Génération de la source (mode basé sur les métadonnées) |
Génération de la source (mode d’optimisation de la sérialisation) |
---|---|---|---|
Plus simple à coder. | ✔️ | ❌ | ❌ |
Plus simple à déboguer. | ❌ | ✔️ | ✔️ |
Prend en charge les membres non publics. | ✔️ | ✔️* | ✔️* |
Prend en charge toutes les personnalisations de sérialisation disponibles. | ✔️ | ❌† | ❌† |
Réduit le temps de démarrage. | ❌ | ✔️ | ✔️ |
Réduit l’utilisation de la mémoire privée. | ❌ | ✔️ | ✔️ |
Élimine la réflexion au moment de l’exécution. | ❌ | ✔️ | ✔️ |
Facilite la réduction de la taille de l’application avec découpage sécurisé. | ❌ | ✔️ | ✔️ |
Augmente le débit de sérialisation. | ❌ | ❌ | ✔️ |
* Le générateur de source prend en charge certains membres non publics, par exemple, des types internes dans le même assembly. † Les contrats générés par la source peuvent être modifiés en utilisant l’API de personnalisation de contrat.
Avantage | Réflexion | Génération de la source (mode basé sur les métadonnées) |
Génération de la source (mode d’optimisation de la sérialisation) |
---|---|---|---|
Plus simple à coder. | ✔️ | ❌ | ❌ |
Plus simple à déboguer. | ❌ | ❌ | ✔️ |
Prend en charge les accesseurs non publics. | ✔️ | ❌ | ❌ |
Prend en charge les propriétés requises. | ✔️ | ❌ | ❌ |
Prend en charge les propriétés d’initialisation uniquement. | ✔️ | ❌ | ❌ |
Réduit le temps de démarrage. | ❌ | ✔️ | ✔️ |
Réduit l’utilisation de la mémoire privée. | ❌ | ✔️ | ✔️ |
Élimine la réflexion au moment de l’exécution. | ❌ | ✔️ | ✔️ |
Facilite la réduction de la taille de l’application avec découpage sécurisé. | ❌ | ✔️ | ✔️ |
Augmente le débit de sérialisation. | ❌ | ❌ | ✔️ |