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 tempo de execução 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 coleta de metadados em tempo de execução, 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. No entanto, o modo de reflexão dá suporte para uso de membros private e acessadores private, mas o modo de geração de fonte não dá. 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 private e escolher o modo de geração de fonte, uma NotSupportedException será lançada 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 código otimizado não oferece suporte a todos os recursos de serialização compatíveis com JsonSerializer. 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 retornar ao código JsonSerializer requer o modo de coleta 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