Fala galera, tudo certo?
Cá estamos mais uma vez falando sobre performance; dessa vez a dica é bem simples e rápida, porém bem útil e proveitosa para ocasiões em que vivemos em nosso dia-a-dia: a utilização de iterações e instância de classes.
Decidi falar sobre esse assunto, porque vi um código em produção fazendo exatamente isso, então certamente vocês podem se deparar com a mesma situação em vossos projetos.
Imagine um caso onde precisamos percorrer uma lista de e-mails e verificar se são válidos ou não. Naturalmente vamos precisar da classe Regex que fica na biblioteca System.Text.RegularExpressions; até aí tudo certo né?
Agora vejam como estava o código de validação antes da refatoração; lembrando que não era uma validação de e-mail, estou usando isso só para fins de exemplo:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var listaDeEmails = new ListaDeEmails().Buscar(); | |
var emailRegex = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; | |
foreach(var email in listaDeEmails) | |
{ | |
var regex = new Regex(emailRegex, RegexOptions.IgnoreCase); | |
var oEmailEstaValido = regex.IsMatch(email); | |
if (oEmailEstaValido) | |
{ | |
//Alguma operacão aqui… | |
} | |
} |
Vejam que a classe Regex é instanciada para cada iteração da lista de e-mails, vejam quanto tempo leva para validarmos uma lista de 1 milhão de e-mails dessa maneira; para medir o tempo, utilizei a classe Stopwatch:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var time = new Stopwatch(); | |
time.Start(); | |
ValidacaoAntiga(); | |
time.Stop(); | |
Console.WriteLine("Tempo: {0}", time.Elapsed); | |
Console.ReadKey(); |
O resultado final é de aproximadamente 26 segundos para realizar a validação da lista toda:
Agora vejam, que com uma pequena mudança, vamos mudar um pouco esse tempo; reparem que na nova validação a classe Regex é instanciada apenas uma vez, antes do início das iterações na lista:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var listaDeEmails = new ListaDeEmails().Buscar(); | |
var emailRegex = @"^(?!\.)(""([^""\r\\]|\\[""\r\\])*""|([-a-z0-9!#$%&'*+/=?^_`{|}~]|(?<!\.)\.)*)(?<!\.)@[a-z0-9][\w\.-]*[a-z0-9]\.[a-z][a-z\.]*[a-z]$"; | |
var regex = new Regex(emailRegex, RegexOptions.IgnoreCase); | |
foreach (var email in listaDeEmails) | |
{ | |
var oEmailEstaValido = regex.IsMatch(email); | |
if (oEmailEstaValido) | |
{ | |
//Alguma operacão aqui… | |
} | |
} |
Só que agora, o resultado é de aproximadamente 4 segundos para a validação dos mesmos 1 milhão de e-mails:
É uma alteração deveras simples, que causa um belo de um impacto, lembrem-se que são os pequenos detalhes que vão dizer se estamos entregando um bom código ou um excelente código!
Os códigos utilizados estão disponíveis no GitHub: https://github.com/vmussak/instancia-loop-example
Por hoje é só isso, qualquer dúvida ou sugestão, estou à disposição! Até mais 😀