Melhorando a performance do Entity Framework com NGen

Olá pessoal,

Em um outro post eu falei bem rapidamente sobre o NGen, que serve para pré-compilar os assemblies de um aplicação, fazendo antecipadamente o trabalho do JIT (Just in Time Compiler).

Só para relembrar um pouco, a figura abaixo mostra o processo de execução de uma aplicação em .Net:

image

Em um processo natural de desenvolvimento em .Net, o que acontece é basicamente o que está na figura acima, ou seja, você escreve seu código, compila e depois executa. Mas na execução entra em ação o JIT, que pega o código gerado (Assembly) e traduz para código nativo, ou linguagem de máquina, que então será executado pelo processador.

Durante a instalação do .Net Framework em um computador, este processo é executado para todos os componmentes do .Net, ou seja, o núcleo doi .Net é automaticamente pré-compilado em seu computador, mas todo o código que você produz não passa por este processo.

Como eu já falei no post anterior, desde a versão 6 o Entity Framework funciona separado do .Net, através da EntityFramework.Dll, que normalmente é baixada pelo NuGet dentro do Visual Studio. Este processo simplesmente baixa a DLL do repositório do NuGet e copia para uma pasta do seu projeto. Isto é ótimo e funciona muito bem!

Muitas pessoas reclamam em fóruns e blogs sobre o tempo de carga inicial do Entity Framework, ou seja, o primeiro comando executado, seja ela qual for, demora um pouco, mas todas as instruções subsequentes são muito rápidas. Logicamente que o desenho do modelo e o comando podem influenciar neste tempo, mas uma coisa que influencia muito é a falta da pré-compilação.

Vamos ver um exemplo bem simples. Vou criar um projeto Console em C# e fazer engenharia reversa usando o Entity Framework PowerTools, que já expliquei em alguns posts anteriores. Então para me acompanhar, crie um projeto do tipo Console no Visual Studio, conforme a figura abaixo:

SNAGHTML4098cce

Agora vamos fazer engenharia reversa no banco de dados Northwind, mas você pode utilizar qualquer outro banco de dados que tenha. PS: não esqueça de instalar o EntityFramework usando NuGet: Install-Package EntityFramework.

image

Agora vou escolher o banco de dados e gerar as classes.

Para mostrar a diferença de performance, vou criar uma simples consulta no EF e para marcar o tempo utilizaremos a classe StopWatch(). Veja abaixo:

   1:  static void Main(string[] args)
   2:          {
   3:              Stopwatch contador = new Stopwatch();
   4:   
   5:              contador.Start();
   6:   
   7:              var db = new NorthwindContext();
   8:   
   9:              var dados = db.Customers;
  10:   
  11:              foreach(var c in dados)
  12:              {
  13:                  Console.WriteLine(c.CompanyName);
  14:              }
  15:              contador.Stop();
  16:              Console.WriteLine("\n\nTempo da consulta: {0} segs.\n\n",contador.Elapsed.TotalSeconds);
  17:          }

 

Veja o resuiltado:

image

Agora vamos utilizar o NGen neste projeto e refazer o teste. Para isto abra um prompt de comando do Visual Studio (como administrador) e execute o comando abaixo:

ngen Install EFPerformance.exe

Você ver algo assim:

image

Repare que além do nosso projeto (EFPerformance.exe) a dll do EntityFramework também foi compilada.

Agora vamos executar o programa novamente, direto da linha de comandos e olhem a diferença de velocidade:

image

Perceba que ficou extremamente mais rápido!!!

Agora se você tem uma aplicação web, você pode melhorar a performance usando comando é aspnet_compiler, mas ele não gera imagens nativas como o NGen, apesar de incrementar a performance através da pré-compilação de alguns arquivos do projeto (.aspx, .ascx, app_code, etc). Se preferir, a IDE do Visual Studio tem esta opção na publicação da aplicação web:

SNAGHTML41af2f8

Espero que tenham gostado das dicas!

Abraços e até a próxima.

Carlos dos Santos.

7 Comments


  1. Ótimo post Carlos, obrigado por compartilhar!

    Abração

    Reply

  2. Ótimo post Carlos, só me tira uma duvida, toda vez que eu compilar um versão do sistema eu devo executar esse comando?

    Reply

    1. Guilherme,

      Neste caso sim, pois a DLL do EF não está no GAC (Global Assembly Cache). Se você for usar sempre a mesma versão do EF, você pode colocar no GAC.

      []s,

      Reply

      1. Normalmente eu sempre costumo usar a ultima versão do Entity, aonde fica o GAC pra mim colocar esse comando?

        Reply

          1. Carlos, estive vendo os 2 artigos e não consegui compreender muito bem, você tem um exemplo de como é feito para que toda vez que eu compilar uma versão nova do sistema e liberar para os clientes não precisar executar manual.

            Obrigado pela ajuda.


  3. Guilherme,
    com ote falei, se a DLL não mudar e estiver no GAC, não precisa recompilar, caso contrário sim.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Anti-spam: complete the taskWordPress CAPTCHA


This blog is kept spam free by WP-SpamFree.