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.