Выбор отражения или создания источника в System.Text.Json
По умолчанию использует отражение времени выполнения для сбора метаданных, System.Text.Json
необходимых для доступа к свойствам объектов для сериализации и десериализации. В качестве альтернативы System.Text.Json
в версии 6.0 и более поздних версий можно использовать функцию создания источника C#, чтобы повысить производительность, уменьшить использование частной памяти и упростить обрезку сборок, что сокращает размер приложения.
Вы можете использовать версию 6.0 или более поздние версии System.Text.Json
в проектах, предназначенных для более ранних платформ. Дополнительные сведения см. в разделе Как получить библиотеку.
В этой статье описываются варианты и приводятся рекомендации по выбору оптимального подхода для вашего сценария.
Общие сведения
Выберите режимы отражения или создания источника на основе следующих преимуществ, которые предлагает каждый из них:
Преимущество | Отражение | Создание источника: Коллекция метаданных |
Создание источника: Оптимизация сериализации |
---|---|---|---|
Проще кодировать и отлаживать. | ✔️ | ❌ | ❌ |
Поддерживает методы доступа, не являющиеся открытыми. | ✔️ | ❌ | ❌ |
Поддерживает обязательные свойства. | ✔️ | ✔️ | ✔️ |
Поддерживает свойства только для инициализации. | ✔️ | ✔️ | ✔️ |
Поддерживает все доступные настройки сериализации. | ✔️ | ❌ | ❌ |
Сокращает время запуска. | ❌ | ✔️ | ❌ |
Снижает использование частной памяти. | ❌ | ✔️ | ✔️ |
Исключает отражение во время выполнения. | ❌ | ✔️ | ✔️ |
Упрощает сокращение размера приложения, безопасного для обрезки. | ❌ | ✔️ | ✔️ |
Увеличивает пропускную способность сериализации. | ❌ | ❌ | ✔️ |
Общие сведения
Выберите режимы отражения или создания источника на основе следующих преимуществ, которые предлагает каждый из них:
Преимущество | Отражение | Создание источника: Коллекция метаданных |
Создание источника: Оптимизация сериализации |
---|---|---|---|
Проще кодировать и отлаживать. | ✔️ | ❌ | ❌ |
Поддерживает методы доступа, не являющиеся открытыми. | ✔️ | ❌ | ❌ |
Поддерживает обязательные свойства. | ✔️ | ❌ | ❌ |
Поддерживает свойства только для инициализации. | ✔️ | ❌ | ❌ |
Поддерживает все доступные настройки сериализации. | ✔️ | ❌ | ❌ |
Сокращает время запуска. | ❌ | ✔️ | ❌ |
Снижает использование частной памяти. | ❌ | ✔️ | ✔️ |
Исключает отражение во время выполнения. | ❌ | ✔️ | ✔️ |
Упрощает сокращение размера приложения, безопасного для обрезки. | ❌ | ✔️ | ✔️ |
Увеличивает пропускную способность сериализации. | ❌ | ❌ | ✔️ |
В следующих разделах описываются эти варианты и их относительные преимущества.
System.Text.Json — метаданные изображения.
Для сериализации или десериализации типа требуется информация о том, JsonSerializer как получить доступ к членам типа. JsonSerializer
требуется следующая информация:
- Как получить доступ к свойствам и полям для сериализации.
- Как получить доступ к конструктору, методу задания свойств и полям для десериализации.
- Сведения о том, какие атрибуты использовались для настройки сериализации или десериализации.
- Конфигурация времени выполнения из JsonSerializerOptions.
Эти сведения называются метаданными.
По умолчанию JsonSerializer
собирает метаданные во время выполнения с помощью отражения. Всякий раз, когда JsonSerializer
необходимо сериализовать или десериализовать тип в первый раз, он собирает и кэширует эти метаданные. Процесс сбора метаданных занимает время и использует память.
Создание источника — режим сбора метаданных
Создание исходного кода можно использовать для перемещения процесса сбора метаданных из времени выполнения в время компиляции. Во время компиляции собираются метаданные и создаются файлы исходного кода. Созданные файлы исходного кода автоматически компилируются как неотъемлемая часть приложения. Этот метод исключает сбор метаданных во время выполнения, что повышает производительность сериализации и десериализации.
Повышение производительности при создании источника может быть существенным. Например, результаты теста показали сокращение времени запуска до 40 % или более, сокращение частной памяти, увеличение скорости пропускной способности (в режиме оптимизации сериализации) и уменьшение размера приложения.
Известные проблемы
По умолчанию* в обоих режимах сериализации поддерживаются только public
свойства и поля. Однако режим отражения поддерживает использование private
методов доступа , а режим создания источника — нет. Например, можно применить атрибут JsonInclude к свойству, у которого private
есть метод задания или метода получения, и оно будет сериализовано в режиме отражения. Режим создания источника поддерживает только public
методы public
доступа свойств или internal
. Если задать [JsonInclude]
для методов доступа, не являющихся открытыми, и выбрать режим создания источника, NotSupportedException
во время выполнения будет выдано исключение .
Как в режиме отражения, так и в режиме создания источника:
- Поддерживаются* только
public
свойства иpublic
поля. - Для десериализации можно использовать только
public
конструкторы.
*Начиная с .NET 7 можно использовать пользовательские контракты JSON для включения private
свойств и полей в сериализацию.
Сведения о других известных проблемах, связанных с созданием источника, см. в статье Проблемы с GitHub, которые помечены как source-generator в репозитории dotnet/runtime .
Режим оптимизации сериализации
JsonSerializer
имеет множество функций, которые настраивают выходные данные сериализации, например имена свойств верблюда и сохранение ссылок. Поддержка всех этих функций приводит к некоторым издержкам производительности. Создание источника может повысить производительность сериализации путем создания оптимизированного кода, который использует Utf8JsonWriter
напрямую.
Оптимизированный код не поддерживает все поддерживаемые функции JsonSerializer
сериализации. Сериализатор определяет, можно ли использовать оптимизированный код, и возвращается к коду сериализации по умолчанию, если указаны неподдерживаемые параметры. Например, JsonNumberHandling.AllowReadingFromString неприменимо к записи, поэтому указание этого параметра не приводит к откату кода по умолчанию.
В следующей таблице показано, какие параметры в JsonSerializerOptions
поддерживаются оптимизированным кодом сериализации:
Параметр сериализации | Поддерживается оптимизированным кодом |
---|---|
Converters | ❌ |
DefaultIgnoreCondition | ✔️ |
DictionaryKeyPolicy | ❌ |
Encoder | ❌ |
IgnoreNullValues | ❌ |
IgnoreReadOnlyFields | ✔️ |
IgnoreReadOnlyProperties | ✔️ |
IncludeFields | ✔️ |
NumberHandling | ❌ |
PropertyNamingPolicy | ✔️ |
ReferenceHandler | ❌ |
TypeInfoResolver | ✔️ |
WriteIndented | ✔️ |
В следующей таблице показано, какие атрибуты поддерживаются оптимизированным кодом сериализации:
attribute | Поддерживается оптимизированным кодом |
---|---|
JsonConverterAttribute | ❌ |
JsonDerivedTypeAttribute | ✔️ |
JsonExtensionDataAttribute | ❌ |
JsonIgnoreAttribute | ✔️ |
JsonIncludeAttribute | ✔️ |
JsonNumberHandlingAttribute | ❌ |
JsonPolymorphicAttribute | ✔️ |
JsonPropertyNameAttribute | ✔️ |
JsonRequiredAttribute | ✔️ |
Если для типа указан не поддерживаемый параметр или атрибут, сериализатор возвращается к коду по умолчанию JsonSerializer
. В этом случае оптимизированный код не используется при сериализации этого типа, но может использоваться для других типов. Поэтому важно провести тестирование производительности с помощью параметров и рабочих нагрузок, чтобы определить, какие преимущества можно получить от режима оптимизации сериализации. Кроме того, для возврата к коду требуется JsonSerializer
режим сбора метаданных. Если выбрать только режим оптимизации сериализации, сериализация может завершиться ошибкой для типов или параметров, которые должны вернуться к коду JsonSerializer
.
Использование режимов создания источника
В большей части документации System.Text.Json показано, как написать код, использующий режим отражения. Сведения об использовании режимов создания источника см. в разделе Использование создания источников в System.Text.Json.