Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

RSS iMasters

[Resolvido] Melhorando o desempenho de aplicativos .NET - Parte 1

Recommended Posts

Neste artigo da série de otimização de código. NET, vamos discutir "iteração e looping". Códigos não otimizados dentro de loops podem levar a problemas de desempenho, que vão desde o aumento do consumo de memória até a exaustão da CPU. Esta seção resume as diretrizes que irão melhorar a interação e eficiência do loop:

Evite campos repetitivos ou acesso à propriedade

Se os seus dados forem estáticos para a duração do loop, obtenha-os antes do loop ao invés de acessar repetidamente um campo ou uma propriedade. O código a seguir mostra uma coleção de ordens sendo processadas para um único cliente.

for ( int item = 0; item < Customer.Orders.Count ; item++ ){

CalculateTax ( Customer.State, Customer.Zip, Customer.Orders[item] );

}

 

Observe que State e Zip são constantes para o loop e podem ser armazenados em variáveis locais ao invés de acesso, em cada passagem pelo circuito, como podemos ver no seguinte código.

 

string state = Customer.State;

string zip = Customer.Zip;

int count = Customers.Orders.Count;

for ( int item = 0; item < count ; item++ )

{

CalculateTax (state, zip, Customer.Orders[item] );

}

Observe que é possível para o compilador fazer essa otimização automaticamente caso estes sejam campos. Já se forem propriedades, é muito menos provável. Se elas forem virtuais, ele não pode ser feito automaticamente.

Otimizar ou evitar operações dispendiosas dentro dos loops

Identifique as operações em seu código loop que podem ser otimizadas. Procure pelo código que causa boxing ou alocações como um efeito colateral. O código a seguir causa um efeito colaterai que é a criação de strings para cada passagem do loop.

String str;

Array arrOfStrings = GetStrings();

for(int i=0; i<10; i++)

{

str+= arrOfStrings;

}

The following code avoids extra string allocations on the heap by using StringBuilder.

StringBuilder sb = new StringBuilder();

Array arrOfStrings = GetStrings();

for(int i=0; i<10; i++)

{

sb.Append(arrOfStrings.GetValue(i));

}

As dicas a seguir podem ser úteis para evitar operações em loop dispendiosas:

  • Esteja ciente do método de chamadas que você faz dentro dos loops. Tenha cuidado com as chamadas de método involuntários e considere o uso de código embutido, onde for apropriado;
Considere o StringBuilder para a concatenação de strings dentro de um loop. Para mais informações, consulte "Operações com strings" mais adiante neste artigo. Ao testar várias condições para sair ou continuar fazendo looping, solicite seus testes, de modo que o mais provável para deixá-lo escapar do loop seja executado primeiro.

Copie o código chamado frequentemente no loop

Se você chama métodos de dentro de um loop repetidamente, considere mudá-lo a fim de reduzir o número de chamadas efetuadas. O compilador JIT geralmente alinha qualquer código de chamada, caso seja simples; mas em cenários mais complexos, otimizar o código é de sua responsabilidade. enquanto você realiza o processo ou atinge os limites de processamento do computador com serviços remotos ou web. O código a seguir mostra um método sendo chamado repetidamente dentro de um loop:

for ( int item = 0 ; item < Circles.Items.Length; item++ ){

CalculateAndDisplayArea(Circles[item]);

}

Considere as seguintes estratégias para reduzir as chamadas efetuadas:

  • Mova o código chamado no loop. Isto reduz o número de chamadas sendo feitas;
Mova a unidade inteira de trabalho para o objeto chamado. O código a seguir modifica o objeto que está sendo chamado e passa todos os dados necessários, de modo que todo o circuito elétrico possa, remotamente, acontecer. Isso é útil para evitar idas e vindas e alivia o trabalho para chamadas locais para um objeto que pode ser hospedado remotamente.
// call function to store all items

OrderProcessing op = new OrderProcessing();

StoreAllOrderItems (Order.Items);

?

class OrderProcessing{

?

public bool StoreAllOrderItems ( Items itemsToInsert )

{

SqlConnection conn = new SqlConnection(?

SqlCommnd cmd = new SqlCommand(?

for ( int item = 0 ; item < orders.Items.Length; item++ ){

// insert order into database

// set parameters on command object

cmd.ExecuteNonQuery();

// insert order item

}

}

. . .

}

Considere substituir a recursão com looping

Cada chamada recursiva adiciona dados para a pilha. Examine seu código e veja se as chamadas recursivas podem ser convertidas para um equivalente de looping. O código a seguir faz chamadas recursivas para realizar uma pequena tarefa de concatenação de string.

Array arr = GetArrayOfStrings();

int index = arr.Length-1;

String finalStr= RecurStr(index);

string RecurStr(int ind){

if (ind<=0)

return ??;

else

return (arr.GetValue(ind)+RecurStr(ind-1));

}

Depois de reescrito, o código agora evita a criação de novos dados sobre a pilha para cada chamada sucessiva e evita, também, uma chamada de método adicional para si mesmo.

string ConcString (Array array)

{

StringBuilder sb = new StringBuilder();

for (int i= array.Length; i>0; i?)

{

sb.Append(array.GetValue(i));

}

return sb;

}

 

Use o For no lugar de Foreach

Use o For no lugar de Foreach (C #) para iterar o conteúdo de coleções em código com desempenho crítico. Foreach em C# e For Each no Visual Basic. NET utilizam um enumerador para fornecer uma navegação melhorada através de matrizes e coleções.

***

Artigo original disponível em: http://blog.monitis.com/index.php/2012/05/01/improving-net-application-performance-part-11-iteration-and-looping/

 

http://imasters.com.br/artigo/25219/dotnet/melhorando-o-desempenho-de-aplicativos-net-parte-11

Compartilhar este post


Link para o post
Compartilhar em outros sites

×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.