Compartilhar via


Modos de geração de origem em System.Text.Json

A geração de origem pode ser usada em dois modos: otimização baseada em metadados e serialização. Este artigo descreve os diferentes modos.

Para obter informações sobre como usar os modos de geração de origem, consulte Como usar a geração de origem em System.Text.Json.

Modo baseado em metadados

Você pode usar a geração de origem para mover o processo de coleta de metadados do runtime para o tempo de compilação. Durante a compilação, os metadados são coletados e os arquivos de código-fonte são gerados. Os arquivos de código-fonte gerados são compilados automaticamente como parte integrante do aplicativo. Essa técnica elimina a coleção de metadados de runtime, o que melhora o desempenho da serialização e desserialização.

As melhorias de desempenho fornecidas pela geração de fonte podem ser substanciais. Por exemplo, os resultados do teste mostraram uma redução de até 40% ou mais no tempo de inicialização, redução da memória privada, aumento da taxa de transferência (no modo de otimização de serialização) e redução do tamanho do aplicativo.

Problemas conhecidos

Somente propriedades e campos public têm suporte por padrão em qualquer modo de serialização (reflexão ou geração de código-fonte). No entanto, o modo de reflexão oferece suporte ao uso de membros private, mas não o modo de geração de fonte. Por exemplo, se você aplicar o atributo JsonInclude a uma propriedade private ou a uma propriedade que tenha um setter ou getter private, irá serializar no modo de reflexão. O modo de geração de fonte dá suporte apenas a membros public ou internal e acessadores public ou internal de propriedades public. Se você definir [JsonInclude] em membros ou acessadores de private e escolher o modo de geração de código-fonte, um NotSupportedException será lançado em tempo de execução.

Para obter informações sobre outros problemas conhecidos com geração de origem, consulte os problemas do GitHub rotulados como "gerador de origem" no repositório dotnet/runtime.

Modo serialização-otimização (caminho rápido)

JsonSerializer possui muitos recursos que personalizam a saída da serialização, como políticas de nomenclatura e preservação de referências. O suporte para todos esses recursos causa alguma sobrecarga de desempenho. A geração de origem pode melhorar o desempenho de serialização gerando código otimizado que usa Utf8JsonWriter diretamente.

O modo de otimização de serialização emite métodos de serialização de caminho rápido, mas não metadados de serialização. A serialização de caminho rápido é restrita no que pode fazer; ele não dá suporte à serialização assíncrona ou a qualquer modo de desserialização.

Além disso, o código otimizado não oferece suporte a todos os recursos de serialização que o JsonSerializer suporta. O serializador detecta se o código otimizado pode ser usado e retorna ao código de serialização padrão se as opções sem suporte forem especificadas. Por exemplo, JsonNumberHandling.AllowReadingFromString não é aplicável à gravação, portanto, especificar essa opção não causa um fallback para o código padrão.

A tabela a seguir mostra para quais opções em JsonSerializerOptions há suporte para serialização de caminho rápido:

Opção de serialização Com suporte para caminho rápido
AllowTrailingCommas ✔️
Converters
DefaultBufferSize ✔️
DefaultIgnoreCondition ✔️
DictionaryKeyPolicy
Encoder
IgnoreNullValues
IgnoreReadOnlyFields ✔️
IgnoreReadOnlyProperties ✔️
IncludeFields ✔️
MaxDepth ✔️
NumberHandling
PropertyNamingPolicy ✔️
ReferenceHandler
TypeInfoResolver ✔️
WriteIndented ✔️

(Não há suporte para as seguintes opções porque elas se aplicam apenas à desserialização: PropertyNameCaseInsensitive, ReadCommentHandling e UnknownTypeHandling.)

A tabela a seguir mostra quais atributos são compatíveis com a serialização de caminho rápido:

Atributo Com suporte para caminho rápido
JsonConstructorAttribute
JsonConverterAttribute
JsonDerivedTypeAttribute ✔️
JsonExtensionDataAttribute
JsonIgnoreAttribute ✔️
JsonIncludeAttribute ✔️
JsonNumberHandlingAttribute
JsonPolymorphicAttribute ✔️
JsonPropertyNameAttribute ✔️
JsonPropertyOrderAttribute ✔️
JsonRequiredAttribute ✔️

Se uma opção ou atributo sem suporte for especificado para um tipo, o serializador retornará ao modo de metadados, supondo que o gerador de origem tenha sido configurado para gerar metadados. Nesse caso, o código otimizado não é usado ao serializar esse tipo, mas pode ser usado para outros tipos. Portanto, é importante fazer testes de desempenho com suas opções e cargas de trabalho para determinar quanto benefício você pode realmente obter do modo de otimização de serialização. Além disso, a capacidade de voltar ao JsonSerializer código requer o modo de metadados. Se você selecionar apenas o modo de otimização de serialização, a serialização poderá falhar para tipos ou opções que precisam retornar ao código JsonSerializer.

Confira também