Desenvolvimento - C#
.NET - Aumentando o desempenho de suas aplicações
Neste artigo eu vou dar algumas dicas de como você pode melhorar o desempenho de sua aplicação .NET.
por José Carlos MacorattiSe você esta migrando sua aplicação para a plataforma .NET (VB.NET ou ASP.NET) ou esta escrevendo novas aplicações para .NET e tem dúvidas e esta procurando maneiras de melhorar o desempenho de sua aplicação chegou ao artigo certo.
Neste artigo eu vou dar algumas dicas (14) de como você pode melhorar o desempenho de sua aplicação .NET . Não vou me ater a detalhes de linguagem nem da plataforma pois estou assumindo que você já tem noções do assunto e conhece os fundamentos da linguagem .NET que escolheu para Vamos lá...
Acelerando sua aplicação
1 - Dispare pouca exceções
Disparar muitas exceções pode ser consumir muito recursos , então não abuse do recurso de lançar exceções e atenha-se somente ao necessário.. Utilize o Perfmon (Sistema de monitoramento) para verificar quantas exceções sua aplicação esta lançando. Pode parecer uma coisa sem importância mas se você não tomar cuidado pode se deparar com código como o do exemplo abaixo onde temos milhares de exceções lançadas sem necessidade alguma:
public static void
Main(string[] args){ int j = 0; for(int i = 0; i < 10000; i++){ try{ j = i; throw new System.Exception(); } catch {} } System.Console.Write(j); return; } |
Em aplicações ASP.NET tenha em mente que o sistema pode também lançar exceções em tempo de execução. Assim Response.Redirect() lança a exceção ThreadAbort.
2 - Utilize laços For para interação com strings
Em C# a palavra chave foreach permite que você percorra os itens em uma lista , string , etc e realize a operação sobre cada item. Esta é uma ferramenta poderosa. Como strings são arrays de caracteres eles podem ser percorridos usando menos recursos do que qualquer outra estrutura.
3 - Prefira usar chamada de funções que realizam diversas tarefas de uma vez
Prefira usar funções que realizam diversas tarefas em uma única chamada do que funções que necessitam diversas chamadas para realizar um certo número de tarefas. Muitas chamadas oneram o sistema.
4 - Prefira usar StringBuilder para manipular strings complexas
Quando uma string é modificada uma nova string será criada em tempo de execução ; a string original vai para o Coletor de Lixo. Quando uma aplicação é modificada diversas vezes repetidamente isto gera uma operação que pode ser muito onerosa. Usando StringBuilder o desempenho é bem melhor. Abaixo temos dois códigos que você pode usar para comparar o desempenho:
namespace ConsoleApplication1.Feedback { using System; public class Feedback { public Feedback(){ texto = "Voce escolheu : \n"; } public string text; public static int Main(string[] args) { Feedback test = new Feedback(); String str = teste.texto; for(int i=0;i<50000;i++) { str = str + "teste_1"; } System.Console.Out.WriteLine("fim"); return 0; } } } |
namespace ConsoleApplication1.Feedback { using System; public class Feedback{ public Feedback() { texto = "Voce escolheu: \n"; } public string text; public static int Main(string[] args) { Feedback teste = new Feedback(); System.Text.StringBuilder SB = new System.Text.StringBuilder(teste.texto); for(int i=0;i<50000;i++) { SB.Append("teste_1"); } System.Console.Out.WriteLine("fim"); return 0; } } } |
Sem usar StringBuilder | Usando StringBuilder |
5 - Faça uma compilação prévia para aplicações Windows Forms
Os Windows Forms usam uma grande quantidade de libraries compartilhadas no SO , e . durante a inicialização da aplicação existe uma perda de desempenho por conta da chamada dos diversos métodos pertinentes. Pré-compilando estas aplicações temos um ganho de desempenho na maioria das situações.
Você pode pré-compilar uma aplicação chamando ngen.exe. Você pode fazer isto durante o tempo de instalação ou antes de você distribuir sua aplicação. O mais comum é usar durante a instalação assim você tenha mais certeza de que a aplicação esta otimizada para a máquina na qual esta sendo instalada
6 - Mantenha o tamanho do buffer para IO entre 4K e 8k
Um buffer entre 4K e 8K lhe dá o melhor desempenho na maioria das vezes nas operações de I/O.
7 - Para acesso a dados use Provedor Gerenciado mais adequado
Faça a escolha certa entre os provedores gerenciados. Existem gerenciadores que são escritos para um banco de dados específico System.Daya.SqlClient por exemplo. Se você utilizar um provedor mais genérico como System.Data.Obdc ao invés de um provedor gerenciado seu desempenho será menor.
8 - Prefira usar Data Reader a Data Set quando possível
Sempre que possível prefira usar um DataReader a um DataSet , isto permite uma rápida leitura dos dados que podem ser guardados em chache. Abaixo uma tabela que demonstra a diferença entre os dois usando os provedores ODBC E SQL. (Os valores maiores representam um melhor desempenho)
DataSet | 801 | 2507 |
DataReader | 1083 | 4585 |
9 - Use Stored Procedures sempre que possível
As Stored procedures são ferramentas com alto desempenho , isto se reflete na velocidade da aplicação.As stored procedures não necessitam ser interpretadas , compiladas ou mesmo ser transmitidas do cliente , nem trafegar pela rede.
10 - Fique atento a utilização de strings de conexões dinâmicas
O pooling de conexões é a maneira mais eficiente de reusar conexões para múltiplas requisições e tem melhor desempenho que ficar abrindo e fechando conexões para cada requisição. Você pode obter um pool de conexões por string de conexão. Se você esta gerando strings de conexão dinamicamente esteja certo de que as strings são idênticas todo o tempo que o pooling ocorrer.
11 - Desabilite o que você não usa
Desabilite a transação automática se você não for precisar dela.. Para o provedor SQL você pode fazer isto via string de conexão:
SqlConnection conn = new SqlConnection("Server=mysrv01;Integrated Security=true;Enlist=false");Ao preencher um DataSet com um DataAdapter não obtenha a informação da chave primária se você não for precisar dela. (Não use define MissingSchemaAction.Addwithkey):
public DataSet SelectSqlSrvRows(DataSet dataset,string connection,string query) { SqlConnection conn = new SqlConnection(connection); SqlDataAdapter adapter = new SqlDataAdapter(); adapter.SelectCommand = new SqlCommand(query, conn); adapter.MissingSchemaAction = MissingSchemaAction.AddWithKey; adapter.Fill(dataset); return dataset; }12 - Evite usar comandos gerados automaticamente
Quando usar um DataAdpter evite usar comandos que são gerados automaticamente. Eles requerem viagens adicionais ao servidor para retornar os meta data.
13 - Mantenha seu DataSet enxuto
Somente preencha um DataSet com os registros que você realmente precisa. . Lembre-se que neste modelo todos os dados são armazenados e representados na memória. (Use filtros em suas expressões SQL)
14 - Use acesso sequencial sempre que possível
Ao usar um DataReader utilize o método CommandBehavior.SequentialAccess. Ele é essencial para trabalhar com dados do tipo Blob.