Reflexão versus geração de fontes em System.Text.Json
Este artigo explica as diferenças entre reflexão e geração de fontes no que diz respeito à System.Text.Json
serialização. Ele também fornece orientação sobre como escolher a melhor abordagem para o seu cenário.
Recolha de metadados
Para serializar ou desserializar um tipo, JsonSerializer precisa de informações sobre como acessar os membros do tipo. JsonSerializer
necessita das seguintes informações:
- Como acessar getters de propriedade e campos para serialização.
- Como acessar um construtor, setters de propriedade e campos para desserialização.
- Informações sobre quais atributos foram usados para personalizar a serialização ou desserialização.
- Configuração em tempo de execução a partir de JsonSerializerOptions.
Estas informações são designadas por metadados.
Reflexão
Por padrão, JsonSerializer coleta metadados em tempo de execução usando reflexão. Sempre que JsonSerializer
precisa serializar ou desserializar um tipo pela primeira vez, ele coleta e armazena em cache esses metadados. O processo de coleta de metadados leva tempo e usa memória.
Geração de fontes
Como alternativa, System.Text.Json
pode usar o recurso de geração de código-fonte C# para melhorar o desempenho, reduzir o uso de memória privada e facilitar o corte de montagem, o que reduz o tamanho do aplicativo. Além disso, certas APIs de reflexão não podem ser usadas em aplicativos AOT nativos, portanto, você deve usar a geração de origem para esses aplicativos.
A geração de fontes pode ser usada em dois modos:
Modo baseado em metadados
Durante a compilação,
System.Text.Json
coleta as informações necessárias para a serialização e gera arquivos de código-fonte que preenchem metadados de contrato JSON para os tipos solicitados.Modo de otimização de serialização (caminho rápido)
JsonSerializer Os recursos que personalizam a saída da serialização, como políticas de nomenclatura e preservação de referência, carregam uma sobrecarga de desempenho. No modo de otimização de serialização, System.Text.Json gera código de serialização otimizado que usa
Utf8JsonWriter
diretamente. Esse código de caminho otimizado ou rápido aumenta a taxa de transferência de serialização.A desserialização de caminho rápido não está disponível no momento. Para obter mais informações, consulte dotnet/runtime issue 55043.
A geração de código-fonte requer System.Text.Json
C# 9.0 ou uma versão posterior.
Comparação de funcionalidades
Escolha modos de reflexão ou de geração de origem com base nos seguintes benefícios que cada um oferece:
Benefício | Reflexão | Geração de fontes (Modo baseado em metadados) |
Geração de fontes (Modo de otimização de serialização) |
---|---|---|---|
Mais simples de codificar. | ✔️ | ❌ | ❌ |
Mais simples de depurar. | ❌ | ✔️ | ✔️ |
Suporta membros não públicos. | ✔️ | ✔️* | ✔️* |
Suporta todas as personalizações de serialização disponíveis. | ✔️ | ❌† | ❌† |
Reduz o tempo de arranque. | ❌ | ✔️ | ✔️ |
Reduz o uso de memória privada. | ❌ | ✔️ | ✔️ |
Elimina a reflexão em tempo de execução. | ❌ | ✔️ | ✔️ |
Facilita a redução do tamanho do aplicativo com segurança de corte. | ❌ | ✔️ | ✔️ |
Aumenta a taxa de transferência de serialização. | ❌ | ❌ | ✔️ |
* O gerador de código-fonte suporta alguns membros não públicos, por exemplo, tipos internos no mesmo assembly. † Os contratos gerados na origem podem ser modificados usando a API de personalização do contrato.