terça-feira, 2 de dezembro de 2008

Parte 2: CType, Convert.To, Directcast e TryCast

No teste de performance e melhores práticas de hoje vamos mostrar a conversão de variáveis de tipo nativo (inteiro, decimal, data, double, etc...) e variáveis de referência (objetos, classes,etc...)

CType x Convert:

A Classe Convert é uma classe utiliátria do .Net Framework, que internamente executa o Ctype ou Directcast após realizar algumas verificações.

Para executar o teste, criamos uma aplicação que possui um Datagridview que mostra o tempo que demorou para executar 1 milhão de vezes o mesmo processo.
Convertemos, em todos os casos, o valor Nothing para o tipo.

Na figura 1 abaixo mostramos um resultado da conversão. A figura esta separada por:

  • Coluna: mostra o tipo para qual o NOTHING foi convertido
  • Linha: Mostra a função utilizada para converter: Convert.ToType ou Ctype


figura 1

Resultado: Podemos notar, que em quase todos os casos o CType é 2x mais rápido que o Convert.To"Type".
O tempo em segundos é mínimo, portanto se você utiliza poucas conversões de cada vez não chega a fazer diferença. Rodamos 1 milhão de vezes cada alteração para conseguir este tempo. Se for ver cada iteração, é instantâneo. Só é possível medir a diferença em grandes escalas mesmo.

Opinião pessoal: Hoje eu já utilizo o Ctype nas conversões e estou mais acostumado. Acredito ficar mais fácil identificar até porquê o próprio Visual Studio marca os CType's com azul, enquanto o Convert.To"Type" fica na mesma cor (na configuração padrão de cores e estilos). Desse jeito, considero melhor visualmente falando e em questões de performance também.


Directcast x TryCast:

O Directcast converte objetos/classes assim como o TryCast. A diferença entre eles, é que se o Directcast não conseguir converter para a classe específicada, ele retorna uma exception, enquanto o TryCast retorna nothing.
No exemplo, criamos um formulário que herda da classe FORM. Disparamos 3000 vezes o DirectCast(MeuFormulario,Form) e o TryCast(MeuFormulario,Form)
O Cast sempre é executado com sucesso (nossa classe MeuFormulario herda da classe FORM), e por isso nenhum exceção foi disparada e o cast nunca retornou nothing.

Resultado: O tempo de cast é exatamente o mesmo. Fizemos 3 testes e os 3 retornaram igual. Isso porquê o teste sempre foi executado com sucesso. Caso o cast fosse impossível ou desse erro, o Directcast dispararia uma Exception e o TryCast retornaria nothing. Em que ponto chegamos disso? Que depende da aplicação do cast. Se você precisa essêncialmente que o seu Cast seja valido, você pode utilizar o directcast dentro de um bloco Try... Catch e tratar a exceção, ou então utilizar o TryCast e verificar se o resultado foi nothing, se for validar da forma certa.

Opinião Pessoal: Como os tempos foram exatamente iguais, é indiferente você utilizar um ou outro, a não ser que sua aplicação necessite de um determinado tratamento. Dificilmente eu preciso que execute um Exception, por isso prefiro tratar com TryCast's, mas isso não passa de opinião pessoal. Façam bom proveito pessoal.

PS; Agradecimentos: Gostaria de agradecer a galera que da um apoio ao blog, principalmente ao Caio Proiete do blog http://www.caioproiete.com/blogs/pontonet
Ele me ensinou bastante coisa sobre performance e melhorias de código, e dessa maneira eu repasso a quem interessa. Da mesma maneira, quem quizer deixar sua ajuda, fique a vontade! Utilize os comentários para nos ajudar

Obrigado a todos!

1 comentários:

Anônimo disse...

Obrigado pela referência!