Melhorando o desempenho de inicialização com o NGen
Observação
EF6 em diante apenas: os recursos, as APIs etc. discutidos nessa página foram introduzidos no Entity Framework 6. Se você estiver usando uma versão anterior, algumas ou todas as informações não se aplicarão.
O .NET Framework dá suporte à geração de imagens nativas para aplicativos e bibliotecas gerenciados como uma maneira de ajudar os aplicativos a iniciar mais rapidamente e, em alguns casos, usar menos memória. As imagens nativas são criadas traduzindo assemblies de código gerenciado em arquivos contendo instruções de máquina nativas antes da execução do aplicativo, evitando que o compilador .NET JIT (Just-In-Time) tenha que gerar as instruções nativas no runtime do aplicativo.
Antes da versão 6, as bibliotecas principais do runtime do EF faziam parte do .NET Framework e as imagens nativas eram geradas automaticamente para elas. A partir da versão 6, todo o runtime do EF foi combinado com o pacote do NuGet EntityFramework. Agora, as imagens nativas precisam ser geradas usando a ferramenta de linha de comando NGen.exe para obter resultados semelhantes.
Observações empíricas mostram que as imagens nativas dos assemblies de runtime do EF podem reduzir entre 1 e 3 segundos do tempo de inicialização do aplicativo.
Como usar o NGen.exe
A função mais básica da ferramenta NGen.exe é "instalar" (ou seja, criar e persistir no disco) imagens nativas para um assembly e todas as suas dependências diretas. Veja como você pode conseguir isso:
Abra uma janela de Prompt de comando como administrador.
Altere o diretório de trabalho atual para a localização das assemblies para as quais você deseja gerar imagens nativas:
cd <*Assemblies location*>
Dependendo do sistema operacional e da configuração do aplicativo, talvez seja necessário gerar imagens nativas para arquitetura de 32 bits, arquitetura de 64 bits ou para ambos.
Para execução de 32 bits:
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install <Assembly name>
Para execução de 64 bits:
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install <Assembly name>
Dica
Gerar imagens nativas para a arquitetura errada é um erro muito comum. Em caso de dúvida, você pode simplesmente gerar imagens nativas para todas as arquiteturas que se aplicam ao sistema operacional instalado no computador.
O NGen.exe também dá suporte a outras funções, como desinstalar e exibir as imagens nativas instaladas, enfileirar a geração de várias imagens etc. Para obter mais detalhes sobre o uso, leia a documentação do NGen.exe.
Quando usar NGen.exe
Quando se trata de decidir para quais assemblies gerar imagens nativas em um aplicativo baseado na versão 6 ou superior do EF, você deve considerar as seguintes opções:
- O principal assembly do runtime do EF, EntityFramework.dll: um aplicativo típico baseado em EF executa uma quantidade significativa de código desse assembly na inicialização ou em seu primeiro acesso ao banco de dados. Consequentemente, a criação de imagens nativas desse assembly produzirá os maiores ganhos no desempenho de inicialização.
- Qualquer assembly de provedor de EF usado pelo seu aplicativo: o tempo de inicialização também pode se beneficiar ligeiramente da geração de imagens nativas delas. Por exemplo, se o aplicativo usar o provedor EF para SQL Server, você irá querer gerar uma imagem nativa para EntityFramework.SqlServer.dll.
- Os assemblies e outras dependências do seu aplicativo: a documentação do NGen.exe abrange critérios gerais para escolher para quais assemblies gerar imagens nativas e o impacto das imagens nativas na segurança, opções avançadas como “associação rígida”, cenários como o uso de imagens nativas na depuração e cenários de perfil, etc.
Dica
Verifique se você mede cuidadosamente o impacto do uso de imagens nativas no desempenho de inicialização e no desempenho geral do aplicativo e compare-as com os requisitos reais. Embora as imagens nativas geralmente ajudem a melhorar o desempenho de inicialização e, em alguns casos, reduzam o uso de memória, nem todos os cenários se beneficiarão igualmente. Por exemplo, na execução em estado estacionário (isto é, uma vez que todos os métodos usados pelo aplicativo tenham sido invocados pelo menos uma vez), o código gerado pelo compilador JIT pode, de fato, produzir um desempenho ligeiramente melhor do que as imagens nativas.
Usando o NGen.exe em um computador de desenvolvimento
Durante o desenvolvimento, o compilador JIT do .NET oferecerá a melhor compensação geral para o código que está sendo alterado com frequência. A geração de imagens nativas para dependências compiladas, como os assemblies de runtime do EF, pode ajudar a acelerar o desenvolvimento e os testes, cortando alguns segundos no início de cada execução.
Um bom lugar para encontrar os assemblies de runtime do EF é o local do pacote NuGet para a solução. Por exemplo, para um aplicativo que usa o EF 6.0.2 com o SQL Server e o .NET 4.5 ou superior, você pode digitar o seguinte em uma janela do Prompt de Comando (lembre-se de abri-lo como administrador):
cd <Solution directory>\packages\EntityFramework.6.0.2\lib\net45
%WINDIR%\Microsoft.NET\Framework\v4.0.30319\ngen install EntityFramework.SqlServer.dll
%WINDIR%\Microsoft.NET\Framework64\v4.0.30319\ngen install EntityFramework.SqlServer.dll
Observação
Isso aproveita o fato de que a instalação das imagens nativas do provedor do EF para SQL Server também instalará, por padrão, as imagens nativas para o assembly de runtime principal do EF. Isso funciona porque o NGen.exe pode detectar que EntityFramework.dll é uma dependência direta do assembly EntityFramework.SqlServer.dll localizado no mesmo diretório.
Criando imagens nativas durante a instalação
O Kit de Ferramentas WiX dá suporte ao enfileiramento da geração de imagens nativas para assemblies gerenciados durante a instalação, conforme explicado neste guia de instruções. Outra alternativa é criar uma tarefa de instalação personalizada que execute o comando NGen.exe.
Verificando se as imagens nativas estão sendo usadas para o EF
Você pode verificar se um aplicativo específico está usando um assembly nativo procurando por assemblies carregados que tenham a extensão “.ni.dll” ou “.ni.exe”. Por exemplo, uma imagem nativa para o assembly de runtime principal do EF será chamada de EntityFramework.ni.dll. Uma maneira fácil de inspecionar os assemblies .NET carregados de um processo é usar o Gerenciador de Processos.
Outros pontos a serem observados
A criação de uma imagem nativa de um assembly não deve ser confundida com o registro do assembly no GAC (Cache de Assembly Global). O NGen.exe permite criar imagens de assemblies que não estão no GAC e, de fato, vários aplicativos que usam uma versão específica do EF podem compartilhar a mesma imagem nativa. Embora o Windows 8 possa criar automaticamente imagens nativas para assemblies colocados no GAC, o runtime do EF é otimizado para ser implantado junto com seu aplicativo e não recomendamos registrá-lo no GAC, pois isso tem um impacto negativo na resolução do assembly e na manutenção de seus aplicativos entre outros aspectos.