Performance de iterações :: while, for, foreach, linq
Quem será o mais rápido? Para descobrir isso criei um projeto de teste da seguinte forma:
Uma classe com o método main() que instancia a classe de teste e imprime os resultados:
1: class Program
2: {
3: static void Main(string[] args)
4: {
5: TestePerf teste = new TestePerf();
6:
7: Produto f = teste.listaProdutos[teste.listaProdutos.Count / 2];
8:
9: List<Resultado> resultados = new List<Resultado>();
10:
11: resultados.Add(teste.AcharLinq(f.idProduto));
12: resultados.Add(teste.AcharForeach(f.idProduto));
13: resultados.Add(teste.AcharFor(f.idProduto));
14: resultados.Add(teste.AcharWhile(f.idProduto));
15:
16: resultados.Sort(delegate(Resultado r1, Resultado r2)
17: {
18: if (Convert.ToInt32(r1.ticks) > Convert.ToInt32(r2.ticks))
19: return 0;
20: else
21: return 1;
22: });
23:
24: foreach (Resultado r in resultados)
25: {
26: Console.WriteLine(r.iterador +
27: "\tTicks:" + r.ticks +
28: "\tMilisegundos: " + r.miliseg);
29: }
30:
31: Console.Read();
32: }
33: }
Uma classe que será o objeto da coleção percorrida:
1: class Produto
2: {
3: public Produto()
4: {
5: this.idProduto = Guid.NewGuid().ToString();
6: }
7:
8: public string idProduto;
9: }
Uma classe para retornar os resultados:
1: class Resultado
2: {
3: public string iterador;
4: public string ticks;
5: public string miliseg;
6:
7: public Resultado(string iterador, string ticks, string miliseg)
8: {
9: this.iterador = iterador;
10: this.ticks = ticks;
11: this.miliseg = miliseg;
12: }
13: }
E uma classe que é responsável pela execução do teste:
1: class TestePerf
2: {
3: public List<Produto> listaProdutos;
4: private const int QUANTIDADE = 500000;
5:
6: public TestePerf()
7: {
8: listaProdutos = new List<Produto>();
9:
10: this.PreencherLista();
11: }
12:
13: private void PreencherLista()
14: {
15: for (int i = 0; i < QUANTIDADE; i++)
16: listaProdutos.Add(new Produto());
17: }
18:
19: public Resultado AcharLinq(string guid)
20: {
21: Stopwatch marcador = new Stopwatch();
22:
23: marcador.Start();
24:
25: Produto g = (from f in listaProdutos
26: where f.idProduto == guid
27: select f).FirstOrDefault();
28:
29: marcador.Stop();
30: return new Resultado(
31: "Linq", marcador.ElapsedTicks.ToString(),
32: marcador.ElapsedMilliseconds.ToString());
33: }
34:
35: public Resultado AcharFor(string guid)
36: {
37: Stopwatch marcador = new Stopwatch();
38: marcador.Start();
39: Resultado result = null;
40:
41: for (int i = 0; i < listaProdutos.Count - 1; i++)
42: {
43: if (listaProdutos[i].idProduto == guid)
44: {
45: marcador.Stop();
46: result = new Resultado(
47: "For", marcador.ElapsedTicks.ToString(),
48: marcador.ElapsedMilliseconds.ToString());
49: break;
50: }
51: }
52:
53: return result;
54: }
55:
56: public Resultado AcharWhile(string guid)
57: {
58: Stopwatch marcador = new Stopwatch();
59: marcador.Start();
60: int cont = 0;
61: Resultado result = null;
62:
63: // Não façam isso em casa!
64: while (true)
65: {
66: if (listaProdutos[cont++].idProduto == guid)
67: {
68: marcador.Stop();
69: result = new Resultado(
70: "While", marcador.ElapsedTicks.ToString(),
71: marcador.ElapsedMilliseconds.ToString());
72: break;
73: }
74: }
75:
76: return result;
77: }
78:
79: public Resultado AcharForeach(string guid)
80: {
81: Stopwatch marcador = new Stopwatch();
82: marcador.Start();
83: Resultado result = null;
84:
85: foreach (Produto f in listaProdutos)
86: {
87: if (f.idProduto == guid)
88: {
89: marcador.Stop();
90: result = new Resultado(
91: "ForEa", marcador.ElapsedTicks.ToString(),
92: marcador.ElapsedMilliseconds.ToString());
93: break;
94: }
95: }
96:
97: return result;
98: }
99: }
Esta última classe possui quatro métodos públicos que recebem um Guid e o pesquisam em uma coleção de ‘produtos’. O tamanho desta coleção é determinada pela variável constante QUANTIDADE, que no teste está com o valor de quinhentos mil.
Um Stopwatch foi usado para marcar o tempo, ele é iniciado quando a iteração começa, parado quando o Guid é encontrado e uma classe de resultado é instanciada com as informações da iteração e retornada ao main().
O teste foi executado cinco vezes e foi feita uma média nos resultados. Quem será que ganhou? Senhores, façam suas apostas!
Primeiro teste:
Segundo teste:
Terceiro:
Quarto:
Último:
E o vencedor é…: While! Tenho que assumir que é um dos iteradores que menos escrevo, normalmente utilizo o foreach e o linq para situações que ficariam muito complexas e/ou ‘feias’ em outros iteradores.
A idéia do post é apenas demonstrar a diferença entre cada um e não pregar qual deve ser utilizado, pois depende muito de cada situaçao e preferência do desenvolvedor. Só fica a dica para optarmos para o mais performático quando não houver diferença na utilização entre eles.
–
Gustavo Vedotti
Visual Studio 2008 Color Themes
Para quem gosta de ser ‘diferente’… Neste blog existem sete temas para baixar, são arquivos em extensões *.vssettings. Para utilizá-los basta abrir o VS2008 ir em Tools > Import and Export Settings Wizard, next, next, next, finish!
Estou usando esse no momento (Desert Nights):

–
Gustavo Vedotti
Compilation Error – BC30456
(último post do ano, uhu!). Ontem me deparei com o seguinte erro:
Server Error in ‘/’ Application.
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.
Compiler Error Message: BC30456: ‘InitializeCulture’ is not a member of ‘ASP.login_alterasenha_aspx’.
Ele começou a acontecer depois que gerei uma versão de publicação do website, conforme a tela abaixo:

Antes o site era deixado no servidor sem estar compilado: .vb (código-fonte) e .aspx (páginas), desta forma o erro não acontecia, o site funcionava perfeitamente. Mas como sabemos isso não é muito aconselhável por questões de segurança e performance (para mais detalhes: http://msdn.microsoft.com/en-us/library/377y0s6t.aspx).
A procura do motivo do erro achei o seguinte post com algumas possíveis soluções, mas nenhuma que solucionasse meu problema. Voltando ao código e algumas horinhas quebrando a cabeça, notei que a página que estava dando erro: AlteraSenha.aspx, implementava a classe Login_AlteraSenha, conforme a diretiva abaixo:
<%@ Page Language=”VB” MasterPageFile=”~/MaterPages/Default2.master” AutoEventWireup=”false”
CodeFile=”AlteraSenha.aspx.vb” Inherits=”Login_AlteraSenha” %>
Ao pesquisar por essa classe, descobri que outra página também a implementava:
<%@ Page Language=”VB” MasterPageFile=”~/MaterPages/Default2.master” AutoEventWireup=”false”
CodeFile=”NovaRevendaLogin.aspx.vb” Inherits=”Login_AlteraSenha” %>
O que fiz? Alterei a segunda página, fazendo-a implementar seu respectivo code-behind e ‘voalá’… Gerei uma nova versão publicada sem erros! Por algum motivo a compilação/publicação do ASP.NEt se confunde quando duas páginas referenciam a mesma classe como code-behind (algo não muito comum de se fazer), bom né?
Feliz ano novo!
–
Gustavo Vedotti
Virtual Tech Days
No último mês de novembro ocorreu uma edição do Virtual Tech Days, uma espécia de convenção on-line feita pela Microsoft, nos dias 24, 25 e 26. As apresentações foram divididas nas seguintes categorias:
Dia 24
- Designer
Dia 25
- Web Development (For Developers)
- Database Development SQL Server (For Developers)
- Cloud Computing & Software + Services (For Developers)
- Save Datacentre Cost through Integrated Physical & Virtual Management (For IT Pros)
- Building a Powerful and Optimized Enterprise Solution on Windows Platform (For IT Pros)
Dia 26
- Client Development (For Developers)
- Tools (For Developers)
- Chalk Talks, Hands-on-Labs & Showcase (For Developers)
- SQL Server Administration (For IT Pros)
- Unified Communication (For IT Pros)
Algumas apresentações que recomendo:
- Architecting Rich Internet Ecommerce Applications Using Silverlight & Commerce Server
- Building Data-Driven Applications with Silverlight 2 and the new Silverlight Control Pack
- Internet Explorer 8 for Web Developers
O bom nisso tudo é que eles disponibilizaram as apresentações e vídeos para download, basta ter um Passport Live =) Para quem se interessar o endereço é esse: http://www.virtualtechdays.com
–
Gustavo Vedotti
Grupo de discussão sobre Commerce Server
Um amigo de trabalho especialista em Commerce Server, teve a iniciativa de criar um grupo de discussão sobre Commerce Server específico para o mercado brasileiro.
O grupo foi criado para troca de experiência, centralização de conhecimento, resoluções de problemas, divulgação de empresas e profissionais que trabalham com Commerce Server e divulgação de cursos e eventos.
Para maiores informações basta acessaro site: www.commerceserver.com.br.
Até
–
Gustavo Vedotti
Comments (3)
Leave a Comment
Leave a Comment