Modalità di generazione di origine in System.Text.Json

La generazione di origine può essere usata in due modalità: ottimizzazione della serializzazione e basata su metadati. Questo articolo descrive le diverse modalità.

Per informazioni su come usare le modalità di generazione di origine, vedere Come usare la generazione di origine in System.Text.Json.

Modalità basata su metadati

È possibile usare la generazione di origine per spostare il processo di raccolta dei metadati dal runtime alla fase di compilazione. Durante la compilazione, i metadati vengono raccolti e vengono generati i file di codice sorgente. I file di codice sorgente generati vengono compilati automaticamente come parte integrante dell'applicazione. Questa tecnica elimina la raccolta di metadati in fase di esecuzione, migliorando le prestazioni della serializzazione e della deserializzazione.

I miglioramenti delle prestazioni offerti dalla generazione di origine possono essere sostanziali. Ad esempio, risultati dei test hanno mostrato fino al 40% o più di riduzione del tempo di avvio, riduzione della memoria privata, aumento della velocità effettiva (in modalità di ottimizzazione della serializzazione) e riduzione delle dimensioni dell'app.

Problemi noti

Solo le proprietà e i campi public sono supportati per impostazione predefinita in modalità di serializzazione. Tuttavia, la modalità reflection supporta l'uso di private funzioni di accesso, mentre la modalità di generazione dell'origine no. Ad esempio, è possibile applicare l'attributo JsonInclude a una proprietà con un private setter o un getter e che verrà serializzata in modalità reflection. La modalità di generazione dell'origine supporta solo funzioni di accesso public e internal di proprietà public. Se si imposta [JsonInclude] sulle funzioni di accesso non pubbliche e si sceglie la modalità di generazione dell'origine, verrà generata una NotSupportedException in fase di esecuzione.

Solo le proprietà e i campi public sono supportati per impostazione predefinita in modalità di serializzazione. Tuttavia, la modalità reflection supporta l'uso di membri private e privatefunzioni di accesso, mentre la modalità di generazione dell'origine no. Ad esempio, se si applica l'attributo JsonInclude a una proprietà private o a una proprietà che ha un private setter o un getter, essa verrà serializzata in modalità reflection. La modalità di generazione dell'origine supporta solo membri public o internal e public o internalfunzioni di accesso di proprietàpublic. Se si imposta [JsonInclude] su membri o funzioni di accesso private e si sceglie la modalità di generazione dell'origine, verrà generata una NotSupportedException in fase di esecuzione.

Per informazioni su altri problemi noti relativi alla generazione di origine, vedere i problemi di GitHub etichettati come "generatore di origine" nel repository dotnet/runtime.

Modalità Ottimizzazione della serializzazione (percorso rapido)

JsonSerializer include molte funzionalità che consentono di personalizzare l'output della serializzazione, ad esempio criteri di denominazione e mantenere i riferimenti. Il supporto per tutte queste funzionalità causa un sovraccarico delle prestazioni. La generazione di origine può migliorare le prestazioni di serializzazione generando codice ottimizzato che usa direttamente Utf8JsonWriter.

Il codice ottimizzato non supporta tutte le funzionalità di serializzazione supportate JsonSerializer. Il serializzatore rileva se il codice ottimizzato può essere usato ed esegue il fallback al codice di serializzazione predefinito se vengono specificate opzioni non supportate. Ad esempio, JsonNumberHandling.AllowReadingFromString non è applicabile alla scrittura, quindi specificando questa opzione non viene generato un fallback nel codice predefinito.

La tabella seguente illustra le opzioni in JsonSerializerOptions supportate dalla serializzazione fast-path:

Opzione di serializzazione Supportato per fast-path
AllowTrailingCommas ✔️
Converters
DefaultBufferSize ✔️
DefaultIgnoreCondition ✔️
DictionaryKeyPolicy
Encoder
IgnoreNullValues
IgnoreReadOnlyFields ✔️
IgnoreReadOnlyProperties ✔️
IncludeFields ✔️
MaxDepth ✔️
NumberHandling
PropertyNamingPolicy ✔️
ReferenceHandler
TypeInfoResolver ✔️
WriteIndented ✔️

Le opzioni seguenti non sono supportate perché si applicano solo alla deserializzazione: PropertyNameCaseInsensitive, ReadCommentHandlinge UnknownTypeHandling.

La tabella seguente illustra gli attributi supportati dalla serializzazione fast-path:

Attributo Supportato per fast-path
JsonConstructorAttribute
JsonConverterAttribute
JsonDerivedTypeAttribute ✔️
JsonExtensionDataAttribute
JsonIgnoreAttribute ✔️
JsonIncludeAttribute ✔️
JsonNumberHandlingAttribute
JsonPolymorphicAttribute ✔️
JsonPropertyNameAttribute ✔️
JsonPropertyOrderAttribute ✔️
JsonRequiredAttribute ✔️

Se per un tipo viene specificata un'opzione o un attributo non supportato, il serializzatore esegue il fallback alla modalità metadati, presupponendo che il generatore di origine sia stato configurato per generare metadati. In tal caso, il codice ottimizzato non viene usato durante la serializzazione di tale tipo, ma può essere usato per altri tipi. È quindi importante eseguire test delle prestazioni con le opzioni e i carichi di lavoro per determinare il vantaggio che è effettivamente possibile ottenere dalla modalità di ottimizzazione della serializzazione. Inoltre, la possibilità di eseguire il fallback al codice JsonSerializer richiede la modalità di raccolta dei metadati. Se si seleziona solo la modalità di ottimizzazione della serializzazione, la serializzazione potrebbe non riuscire per tipi o opzioni che devono eseguire il fallback al codiceJsonSerializer.

Vedi anche