Udostępnij za pośrednictwem


Tryby generowania źródła w programie System.Text.Json

Generowanie źródła może być używane w dwóch trybach: optymalizacji opartej na metadanych i serializacji. W tym artykule opisano różne tryby.

Aby uzyskać informacje na temat używania trybów generowania źródła, zobacz Jak używać generowania źródła w programie System.Text.Json.

Tryb oparty na metadanych

Generowanie źródła umożliwia przeniesienie procesu zbierania metadanych z czasu wykonywania do czasu kompilacji. Podczas kompilacji metadane są zbierane, a pliki kodu źródłowego są generowane. Wygenerowane pliki kodu źródłowego są automatycznie kompilowane jako integralna część aplikacji. Ta technika eliminuje zbieranie metadanych w czasie wykonywania, co zwiększa wydajność zarówno serializacji, jak i deserializacji.

Ulepszenia wydajności zapewniane przez generowanie źródła mogą być znaczne. Na przykład wyniki testów pokazały do 40% lub więcej czasu uruchamiania, zmniejszenie pamięci prywatnej, zwiększenie szybkości przepływności (w trybie optymalizacji serializacji) i zmniejszenie rozmiaru aplikacji.

Znane problemy

Tylko public właściwości i pola są domyślnie obsługiwane w trybie serializacji. Jednak tryb odbicia obsługuje użycie elementów private członkowskich i private metod dostępu, podczas gdy tryb generowania źródła nie. Jeśli na przykład zastosujesz atrybut JsonInclude do private właściwości lub właściwości, która ma private parametr setter lub getter, zostanie serializowany w trybie odbicia. Tryb generowania źródła obsługuje tylko public internal elementy członkowskie i public lub internal metody dostępu public właściwości. Jeśli ustawisz [JsonInclude] private elementy członkowskie lub metody dostępu i wybierzesz tryb generowania źródła, NotSupportedException element zostanie zgłoszony w czasie wykonywania.

Aby uzyskać informacje o innych znanych problemach z generowaniem źródła, zobacz problemy z usługą GitHub oznaczone jako "source-generator" w repozytorium dotnet/runtime .

Tryb optymalizacji serializacji (szybka ścieżka)

JsonSerializer Ma wiele funkcji, które umożliwiają dostosowanie danych wyjściowych serializacji, takich jak zasady nazewnictwa i zachowanie odwołań. Obsługa wszystkich tych funkcji powoduje pewne obciążenie związane z wydajnością. Generowanie źródła może zwiększyć wydajność serializacji, generując zoptymalizowany kod, który używa Utf8JsonWriter bezpośrednio.

Zoptymalizowany kod nie obsługuje wszystkich funkcji serializacji, które JsonSerializer obsługują. Serializator wykrywa, czy zoptymalizowany kod może być używany i wraca do domyślnego kodu serializacji, jeśli nie są określone nieobsługiwane opcje. Na przykład JsonNumberHandling.AllowReadingFromString nie ma zastosowania do pisania, dlatego określenie tej opcji nie powoduje powrotu do domyślnego kodu.

W poniższej tabeli przedstawiono opcje JsonSerializerOptions obsługiwane przez serializacji szybkiej ścieżki:

Opcja serializacji Obsługiwane w przypadku szybkiej ścieżki
AllowTrailingCommas ✔️
Converters
DefaultBufferSize ✔️
DefaultIgnoreCondition ✔️
DictionaryKeyPolicy
Encoder
IgnoreNullValues
IgnoreReadOnlyFields ✔️
IgnoreReadOnlyProperties ✔️
IncludeFields ✔️
MaxDepth ✔️
NumberHandling
PropertyNamingPolicy ✔️
ReferenceHandler
TypeInfoResolver ✔️
WriteIndented ✔️

(Następujące opcje nie są obsługiwane, ponieważ dotyczą tylko serializacji: PropertyNameCaseInsensitive, ReadCommentHandlingi UnknownTypeHandling.)

W poniższej tabeli przedstawiono, które atrybuty są obsługiwane przez serializacji szybkiej ścieżki:

Atrybut Obsługiwane w przypadku szybkiej ścieżki
JsonConstructorAttribute
JsonConverterAttribute
JsonDerivedTypeAttribute ✔️
JsonExtensionDataAttribute
JsonIgnoreAttribute ✔️
JsonIncludeAttribute ✔️
JsonNumberHandlingAttribute
JsonPolymorphicAttribute ✔️
JsonPropertyNameAttribute ✔️
JsonPropertyOrderAttribute ✔️
JsonRequiredAttribute ✔️

Jeśli dla typu określono nieobsługiwaną opcję lub atrybut, serializator powraca do trybu metadanych, zakładając, że generator źródła został skonfigurowany do generowania metadanych. W takim przypadku zoptymalizowany kod nie jest używany podczas serializacji tego typu, ale może być używany dla innych typów. Dlatego ważne jest przeprowadzenie testów wydajnościowych przy użyciu opcji i obciążeń, aby określić, ile korzyści można uzyskać z trybu optymalizacji serializacji. Ponadto możliwość powrotu do JsonSerializer kodu wymaga trybu zbierania metadanych. W przypadku wybrania tylko trybu optymalizacji serializacji serializacja może zakończyć się niepowodzeniem dla typów lub opcji, które muszą wrócić do JsonSerializer kodu.

Zobacz też