Artigo do tipo Exemplos Práticos
Recursos especiais neste artigo:
Conteúdo sobre boas práticas.
Profiler no Visual Studio
Profiling de aplicações é um conjunto de técnicas e ferramentas que nos ajudam a compreender e diagnosticar diversos aspectos de nossas aplicações através da coleta de dados da execução do mesmo. Neste artigo veremos como utilizar o Profiler no Visual Studio 2012, quais são as categorias de dados que ele disponibiliza e como analisar os seus resultados. Durante o artigo, iremos identificar um problema de desempenho de uma aplicação de exemplo com a ajuda dessa ferramenta.


Em que situação o tema é útil

Este tema é útil quando nossas aplicações não funcionam com o desempenho desejado e não há sinais claros da causa do problema, nos auxiliando com a geração de dados e indícios importantes para a análise e solução destes problemas.

Um dos maiores benefícios que a Tecnologia da Informação traz para as pessoas é a agilidade em executar processos que manualmente levariam muito tempo. Essa é uma premissa que cada vez mais exigida, dado à competitividade que existe hoje. Bancos, seguradoras, fábricas e vários outros seguimentos buscam um diferencial para se destacar dentro do seu mercado de atuação e por consequência, os softwares precisam acompanhar este movimento.

Mesmo que uma aplicação funcione corretamente, faça os cálculos corretos e gere os devidos relatórios, não é aceitável que demore em disponibilizar seus resultados. É por isso que desempenho torna-se um requisito técnico que deve sempre andar junto às funcionalidades desenvolvidas.

O Visual Studio, desde sua versão 2005, disponibiliza ferramentas que auxiliam na identificação de problemas de desempenho, apelidados como “gargalos”. A ideia em se utilizar o Profiler é bem simples: Dentro do Visual Studio, iniciamos uma sessão de desempenho (Performance Session). Essa sessão acompanha a execução da aplicação que desejamos analisar, e quando finalizada, um arquivo contendo os dados colhidos durante o processo é disponibilizado. Podemos então visualizar os dados desse arquivo em diversos relatórios disponíveis na IDE do Visual Studio, cada um focando em determinado aspecto para assessorar a nossa análise. Além disso, a ferramenta permite que seja feita uma comparação entre o resultado de duas sessões de desempenho, permitindo verificarmos o ganho real feito entre uma versão de código com problemas de desempenho e outra que foi otimizada. É isso que iremos ver neste artigo!

Tipos de profiling

O conceito de profiling envolve a coleta e análise de dados de uma aplicação visando identificar problemas. O Profiler do Visual Studio 2012 disponibiliza quatro tipos de análise.

O primeiro tipo é amostragem (sampling), indicado para analisar em qual parte do código ocorre um alto uso de CPU. Funciona da seguinte maneira: em determinados intervalos de tempo (o padrão é uma amostra a cada 10 milhões de ciclos da CPU), o Profiler interrompe a execução do processamento da máquina e analisa o código que está sendo executado no momento. Caso ele não seja da aplicação que estamos analisando, os dados coletados dessa pilha de execução são descartados. Entretanto, se o código em execução for parte da aplicação em análise, o Profiler adiciona essas informações recuperadas na lista de amostras. É importante notar que esta característica faz com que essa coleta de dados prejudique o mínimo possível a execução do sistema em análise.

O segundo tipo é a instrumentação (instrumentation), também útil para a análise de uso de CPU. Entretanto, provê bem mais detalhes que a amostragem, pois considera cada chamada de método que ocorre na execução do código da aplicação. Com isso, podemos saber quantas vezes determinada função foi executada e qual foi o tempo gasto apenas com ela. Com isso, fica fácil descobrir quais são os métodos “vilões” no seu código e dar maior atenção a eles, de maneira que sejam reescritos de forma otimizada. O segredo da instrumentação está na alteração do código da sua aplicação que está sendo analisada pelo Profiler. Em cada método que existe no seu código é incluída uma chamada que marca quando a sua execução começou e quando terminou (o Profiler altera a DLL resultante da compilação do seu código). Com isso, é possível fazer contagem de quantas vezes um método foi chamado e durante quanto tempo na sua aplicação esta função ficou executando.

Enquanto temos a vantagem de dados mais detalhados que a amostragem, a instrumentação onera em muito o desempenho da aplicação. Por isso, é mais indicada para ser executada em ambientes de desenvolvimento, onde não há grande impacto na demora e maior consumo de recursos computacionais.

Um terceiro tipo de profiling é a análise de memória. Às vezes, sua aplicação pode estar executando em um tempo aceitável, entretanto, tem um alto uso de memória, muitas vezes levando a um problema de estouro da mesma (OutOfMemoryException). O sintoma geral pode ser constatado utilizando o Monitor de Desempenho do Windows (Performance Monitor, ou perfmon). A Figura 1 mostra um exemplo de aplicação cujo consumo de memória é crescente, indicando que objetos estão sendo alocados em memória, mas não estão sendo limpos; uma vez que o correto seria um gráfico do tipo “montanha-russa”: quando ele chega num nível alto, há uma queda brusca, indicando que o .NET (Garbage Collector) efetuou uma coleta de objetos que não estão mais sendo utilizados. Para se chegar mais perto de onde está ocorrendo o problema de uso excessivo de memória, a análise do Profiler nos permite identificar quais são os métodos que mais alocam memória.


Figura 1. Gráficos com comportamentos diferentes de acordo com o uso de memória

Esta análise de memória é feita de forma similar à amostragem, ou seja, não há alteração de código, mas sim a coleta de dados do processo de tempos em tempos. Portanto, não é tão invasiva quanto ao modo usado pela instrumentação.

A última forma disponível para efetuar o profiling de aplicações .NET dentro do Visual Studio é a análise de concorrência. Com ela, é possível descobrir o comportamento da sua aplicação em relação ao processamento paralelo que eventualmente faz, permitindo encontrar problemas de sincronização (duas tarefas acessando dados de um mesmo objeto, ao mesmo tempo) e contenção (quando um objeto está esperando um recurso comum ser liberado).

A mensuração de desempenho de código ou memória não é a única indicação do uso de um profiler. Podemos utilizá-lo também para simular objetos de testes, e é isso exatamente que é feito no Fakes e na sua versão anterior, o Moles, frameworks de testes criados pela Microsoft.

Criando uma sessão do Profiler

Para poder rodar o Profiler é necessário criar uma sessão de desempenho (Performance Session). Isso é feito através do menu “Analyse”, conforme podemos ver na Figura 2. Existem algumas opções para essa criação, todas com o mesmo resultado final, mas com alguns passos a mais ou a menos. São eles:

“Start Performance Analysis” – Inicia o Profiler no modo de amostragem para o projeto padrão da solução no Visual Studio. Tão logo a aplicação entre em execução, o Profiler já estará coletando os dados.

· “Start Performance Analysis Paused” – Similar à opção anterior, porém aguarda o seu comando para começar a processar os dados amostrais.

· “Launch Performance Wizard...” – Exibe a tela da Figura 3 permitindo que você escolha o tipo de análise que será feita, quais projetos serão considerados no processo, dentre outros.

· “Profiler à New Profiler Session” – esta opção permite criar uma sessão de profiling do zero, onde você pode especificar cada detalhe antes da sua execução. Iremos utilizar essa opção exatamente para demonstrar alguns conceitos importantes.


Figura 2. Menu Analyse no Visual Studio 2012


Figura 3. Performance Wizard

Ao se escolher a última opção de criação de uma nova sessão do Profiler que citamos, é exibida a aba “Performance Explorer”, que serve de repositório para todas as sessões existente. Cada sessão possui duas pastas. A primeira irá armazenar os relatórios que serão gerados ao término da análise (como uma sessão pode ser executada mais de uma vez, faz sentido termos acesso aos resultados de cada execução). A segunda armazena quais são os componentes que serão analisados, que podem ser tanto projetos existentes na solução aberta no Visual Studio, componentes .NET (DLL) ou mesmo websites que estejam executando no IIS local. São essas as opções que estão destacadas na Figura 4. Clicando com o botão direito sobre a sessão, teremos acesso às suas propriedades. Nela podemos configurar várias opções, que veremos a seguir.


Figura 4. Incluindo projetos, sites e componentes para análise

A primeira guia “General” (Figura 5), contém opções que definem o tipo de profiling que será executado. Veja que a primeira opção solicitada é o tipo (profiling collection), tendo as opções Sampling, Instrumentation e Concurrency, comentadas anteriormente. Exite uma quarta opção de profiling, que é a de memória. O profiling de memória nada mais é que a opção de Sampling ou Instrumentation com a checkbox “Collect .NET object allocation information” selecionada. Além disso, em relação ao profiling de memória, temos também a opção “Also collect .NET object lifetime information”, que recupera informações do tempo de vida que os objetos alocados em memória tiveram durante a análise. As demais opções da guia apenas servem para definir a localização e nomenclatura dos arquivos de resultados gerados.

...
Quer ler esse conteúdo completo? Tenha acesso completo