Neste artigo veremos algumas dicas para resolver problemas comuns de desempenho em aplicações para Windows Mobile com o .Net compact framework. Devido às limitações de hardware, quando desenvolvemos para dispositivos móveis, precisamos nos preocupar com a performance da aplicação e evitar as "bad pratices". A maioria das orientações foram oferecidas diretamente pelo time de desenvolvimento do NET Compact Framework, porém, devem ser usadas apenas quando for necessário para evitar códigos confusos, pouco reaproveitáveis e de difícil manutenção.
String imutável - Essa é aquela velha história que todo programador Java e/ou .Net já deve saber. Strings são imutáveis, ou seja, não é possível fazer qualquer modificação em uma String. Quando você utilizar a concatenação um novo objeto String é criado. Isso tem um alto custo e deve ser evitado SEMPRE. Ao invés de usar concatenação opte por utilizar StringBuilder.
Código a ser evitado:
String str = "string inicial";
for (int i = 0; i < 1000; i++) {
str += "String concatenada";
}
Código a ser usado:
StringBuilder str = new StringBuilder();
for (int i = 0; i < 1000; i ++) {
str.Append("String concatenada");
}
Uso de XML - Quando um XML for maior que 64 Kb utilize System.Xml.XmlReader, ao invés de System.Xml.XmlDocument. Para melhorar o desempenho defina a propriedade 'IgnoreWhiteSpace' como true para ignorar os espaços em branco não significativos (usados apenas para facilitar a leitura humana). Sempre que puder utilize nomes curtos para elementos e atributos, pois, isso reduz o tamanho final do arquivo.
Reflection - Não adianta, reflections são lentos em qualquer lugar, inclusive no Desktop. Em dispositivos móveis são de 10 a 100 vezes mais lentos, portanto evite sempre. Substitua os Reflection por métodos Factory (Design patern) e uso de interfaces. Não esqueça que Web Services utilizam Reflection. Uma boa dica é utilizar o padrão singleton e manter apenas uma instância do Web Service para a aplicação inteira.
Exemplo para utilizar Web Service e evitar desperdícios de recursos com reflection.
//classe que irá gerenciar o web service
public static class WebService() {
//instância do web service
private static WSCorreios www = null;
//método estático usado para pegar a instância do Web Service.
public static getWSCorreios() {
if (www == null)
www = new WSCorreios();
return www;
}
}
//classe que irá usar o WebService
public class usarWS() {
//construtor
public usarWS() {
}
//pega a instância do Web Service
WSCorreios www = WebService.getWSCorreios();
//usa métodos do Web Service
www.getCep();
}
}
Boxing e Unboxing - Tipos primitivos são armazenados na pilha (STACK) e por isso não envolvem o Garbage Collector. Isso é muito bom para o desenvolvedor porque economiza muitos recursos, porém, quando é feito o boxing é guardado um tipo por referência no HEAP, e por isso a limpeza será controlada pelo Garbage Collector. Procure evitar usar boxing.
Object - Quando a aplicação acessa uma variável declarada como Object o CLR é obrigado à realizar a checagem de tipo e procurar esse objeto em tempo de execução, portanto, usar o tipo Object sempre gera um custo maior e muitas vezes desnecessário.
Collection - Sempre utilize arrays simples para tipos primitivos e System.Collection.Generic (List) para coleções de objetos. Evite o uso de ArrayList para guardar qualquer coisa, pois além de fazer o boxing (desnecessários para tipos primitivos) ainda usa Object para guardar os objetos.
Melhor maneira para guardar coleçoes de tipos primitivos:
int[] Lista = new int[100000];
for(int i = 0; i < 100000; i++) {
Lista[i] = i;
}
Melhor maneira para guardar coleções de objetos:
List Lista = new List(100000);
for(int i = 0; i < 100000; i++) {
Lista.Add(i);
}
Pior maneira para guardar qualquer coisa:
ArrayList Lista = new ArrayList(100000);
for(int i = 0; i < 100000; i++) {
Lista.Add(i);
}
####################
Referência:
http://msdn.microsoft.com/en-us/library/1766918e.aspx
http://msdn.microsoft.com/en-us/library/ms172524.aspx
Giorge Henrique Abdala
Perfeito.
ResponderExcluirEstava procurando exatamente isso. Estou com problemas de performance para pegar dados de um web service e preencher um banco de dados. Suas dicas me ajudaram muito, porém, agora estou com problemas para fazer os insert e update. Tem alguma dica especial para isso??
Olá Matheus,
ResponderExcluirOperações com Insert/Update normalmente são lentas mesmo. Se o volume de dados for grande você pode pensar em retirar os índices das tabelas antes dos Insert´s e recria-los depois. Assim a engine do BD não precisa atualizar todos os índices.
Uma coisa primordial é usar SqlCeResultSet para fazer os Insert/Update, visto que são muito mais rápidos que SQLPrepared. Nunca utilize String SQL com concatenação, pois é lento de mais.
Espero ter ajudado.