Modos de geração de origem em System.Text.Json
A geração de origem pode ser usada em dois modos: baseado em metadados e otimização de 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 no 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 da desserialização.
As melhorias de desempenho proporcionadas pela geração de origem podem ser substanciais. Por exemplo, os resultados do teste mostraram até 40% ou mais de redução do tempo de inicialização, redução da memória privada, aumento da velocidade de transferência (no modo de otimização de serialização) e redução do tamanho do aplicativo.
Problemas conhecidos
Somente public
propriedades e campos são suportados por padrão em qualquer modo de serialização. No entanto, o modo de reflexão suporta o uso de acessadores, enquanto o modo de geração de private
origem não. Por exemplo, você pode aplicar o atributo JsonInclude a uma propriedade que tenha um private
setter ou getter e ela será serializada no modo de reflexão. O modo de geração de origem suporta apenas public
ou internal
acessadores de public
propriedades. Se você definir [JsonInclude]
em acessadores não públicos e escolher o modo de geração de origem, um NotSupportedException
será lançado em tempo de execução.
Somente public
propriedades e campos são suportados por padrão em qualquer modo de serialização. No entanto, o modo de reflexão suporta o uso de membros e private
acessadores, enquanto o modo de geração de private
origem não. Por exemplo, se você aplicar o atributo JsonInclude a uma propriedade ou a uma private
propriedade que tenha um private
setter ou getter, ele será serializado no modo de reflexão. O modo de geração de origem suporta apenas public
ou internal
membros e public
/ou internal
acessadores de public
propriedades. Se você definir [JsonInclude]
private
membros ou acessadores e escolher o modo de geração de origem, um NotSupportedException
será lançado em tempo de execução.
Para obter informações sobre outros problemas conhecidos com a geração de código-fonte, consulte os problemas do GitHub rotulados como "gerador de código-fonte" no repositório dotnet/runtime .
Modo de otimização de serialização (caminho rápido)
JsonSerializer
tem 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 código-fonte pode melhorar o desempenho da serialização gerando código otimizado que usa Utf8JsonWriter
diretamente.
O código otimizado não suporta todos os recursos de serialização suportados JsonSerializer
. O serializador deteta se o código otimizado pode ser usado e retorna ao código de serialização padrão se opções sem suporte forem especificadas. Por exemplo, JsonNumberHandling.AllowReadingFromString não é aplicável à escrita, portanto, especificar essa opção não causa um fallback para o código padrão.
A tabela a seguir mostra quais opções são JsonSerializerOptions
suportadas pela serialização de caminho rápido:
Opção de serialização | Suportado para fast-path |
---|---|
AllowTrailingCommas | ✔️ |
Converters | ❌ |
DefaultBufferSize | ✔️ |
DefaultIgnoreCondition | ✔️ |
DictionaryKeyPolicy | ❌ |
Encoder | ❌ |
IgnoreNullValues | ❌ |
IgnoreReadOnlyFields | ✔️ |
IgnoreReadOnlyProperties | ✔️ |
IncludeFields | ✔️ |
MaxDepth | ✔️ |
NumberHandling | ❌ |
PropertyNamingPolicy | ✔️ |
ReferenceHandler | ❌ |
TypeInfoResolver | ✔️ |
WriteIndented | ✔️ |
(As seguintes opções não são suportadas porque se aplicam apenas à serialização: PropertyNameCaseInsensitive, ReadCommentHandlinge UnknownTypeHandling.)
A tabela a seguir mostra quais atributos são suportados pela serialização de caminho rápido:
Atributo | Suportado para fast-path |
---|---|
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 recorrer ao JsonSerializer
código 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 voltar ao JsonSerializer
código.