System.Text.Json のソース生成のモード

ソース生成は、メタデータベースとシリアル化の最適化の 2 つのモードで使用できます。 この記事では、さまざまなモードについて説明します。

ソース生成モードの使用方法については、「System.Text.Json でソース生成を使用する方法」を参照してください。

メタデータベースのモード

ソース生成を使用して、メタデータ コレクション プロセスを実行時からコンパイル時に移動できます。 コンパイル中に、メタデータが収集され、ソース コード ファイルが生成されます。 生成されたソース コード ファイルは、アプリケーションの不可欠な部分として自動的にコンパイルされます。 この手法では、実行時のメタデータ コレクションが不要になるため、シリアル化と逆シリアル化の両方のパフォーマンスが改善されます。

ソース生成によってパフォーマンスが大幅に改善する可能性があります。 たとえば、テスト結果には、最大で 40% 以上の起動時間の短縮、プライベート メモリの削減、スループット速度の増加 (シリアル化の最適化モードで)、アプリ サイズの縮小が示されています。

既知の問題

どちらのシリアル化モードでも、既定では public プロパティとフィールドのみがサポートされます。 ただし、リフレクション モードでは private "アクセサー" の使用がサポートされますが、ソース生成モードではサポートされません。 たとえば、private セッターまたはゲッターのあるプロパティに JsonInclude 属性を適用できます。リフレクション モードでシリアル化されます。 ソース生成モードでサポートされるのは、public プロパティの public アクセサーまたは internal アクセサーだけです。 非パブリック アクセサーで [JsonInclude] を設定し、ソース生成モードを選択する場合、NotSupportedException が実行時にスローされます。

どちらのシリアル化モードでも、既定では public プロパティとフィールドのみがサポートされます。 ただし、リフレクション モードでは private メンバーと private "アクセサー" の使用がサポートされますが、ソース生成モードではサポートされません。 たとえば、 JsonInclude 属性private プロパティまたは private セッターまたはゲッターを持つプロパティに適用すると、リフレクション モードでシリアル化されます。 ソース生成モードでは、 public または internal メンバーと、 public プロパティの public アクセサーまたは internal アクセサーのみがサポートされます。 private メンバーまたはアクセサーに [JsonInclude] を設定し、ソース生成モードを選択すると、実行時に NotSupportedException がスローされます。

ソース生成に関するその他の既知の問題の詳細については、dotnet/runtime リポジトリで "source-generator" というラベルが付いている GitHub イシューに関する記事を参照してください。

シリアル化最適化 (高速パス) モード

JsonSerializer には、 名前付けポリシーの参照の保持など、シリアル化の出力をカスタマイズ多くの機能があります。 これらすべての機能をサポートすると、パフォーマンスのオーバーヘッドが発生します。 ソース生成によって Utf8JsonWriter を直接使用する最適化されたコードが生成されることにより、シリアル化のパフォーマンスが向上します。

最適化されたコードは、JsonSerializer でサポートされているすべてのシリアル化機能をサポートしていません。 シリアライザーでは、最適化されたコードを使用できるかどうかが検出され、サポートされていないオプションが指定されている場合は既定のシリアル化コードにフォールバックします。 たとえば、JsonNumberHandling.AllowReadingFromString は書き込みには適用されません。したがって、このオプションを指定しても、既定のコードにフォールバックすることはありません。

次の表に、高速パス シリアル化により JsonSerializerOptions のどのオプションがサポートされているのかを示します。

シリアル化のオプション 高速パスでサポートされます
AllowTrailingCommas ✔️
Converters
DefaultBufferSize ✔️
DefaultIgnoreCondition ✔️
DictionaryKeyPolicy
Encoder
IgnoreNullValues
IgnoreReadOnlyFields ✔️
IgnoreReadOnlyProperties ✔️
IncludeFields ✔️
MaxDepth ✔️
NumberHandling
PropertyNamingPolicy ✔️
ReferenceHandler
TypeInfoResolver ✔️
WriteIndented ✔️

(次のオプションは、"逆" シリアル化にのみ適用されるため、サポートされていません: PropertyNameCaseInsensitiveReadCommentHandlingUnknownTypeHandling)。

次の表に、高速パス シリアル化でどの属性がサポートされているかを示します。

属性 高速パスでサポートされます
JsonConstructorAttribute
JsonConverterAttribute
JsonDerivedTypeAttribute ✔️
JsonExtensionDataAttribute
JsonIgnoreAttribute ✔️
JsonIncludeAttribute ✔️
JsonNumberHandlingAttribute
JsonPolymorphicAttribute ✔️
JsonPropertyNameAttribute ✔️
JsonPropertyOrderAttribute ✔️
JsonRequiredAttribute ✔️

サポートされていないオプションまたは属性が型に対して指定されている場合、ソース ジェネレーターがメタデータを生成するように構成されていると仮定して、シリアライザーはメタデータ モードにフォールバックします。 その場合、最適化されたコードは、その型をシリアル化するときには使用されませんが、他の型に使用することができます。 したがって、オプションとワークロードを使用してパフォーマンス テストを実行し、実際にシリアル化最適化モードから得られるベネフィットを判断することが重要です。 また、JsonSerializer コードにフォールバックする機能には、メタデータコレクション モードが必要です。 シリアル化最適化モードのみを選択した場合、JsonSerializer コードへのフォールバックを必要とする型またはオプションについてはシリアル化が失敗する場合があります。

関連項目