.Net 5 Regex Performance
Wellington Martins
Posted on October 11, 2021
Olá pessoal!
Hoje vamos fazer um teste de performance utilizando regex com .net 5.
Para esse teste criaremos um console application com a instalção de 2 pacotes nuget:
dotnet new console —name TestePerformanceRegex
dotnet add package BenchmarkDotNet
dotnet add package Bogus
BenchmarkDotNet é o pacote responsável por realizar nosso benchmark.
Bogus é o pacote responsável por gerar os dados para nossos testes.
Nosso console app será composto por duas classes:
- Program.cs
- TesteRegex.cs
Nossa classe Program.cs será dessa forma:
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<TesteRegex>();
}
}
Nossa classe TesteRegex.cs deverá ter o annotation [MemoryDiagnoser]
[MemoryDiagnoser]
public class TesteRegex
{
}
Agora vamos criar uma classe Usuário, onde teremos E-mail e Login:
public class Usuario
{
public string Email { get; set; }
public string Login{ get; set; }
}
Agora dentro da classe TesteRegex, vamos fazer o seguinte:
private static readonly List<Usuario> FakeUsuarios = new Faker<Usuario>()
.UseSeed(420)
.RuleFor(r => r.Email, faker => faker.Person.Email)
.RuleFor(r => r.Login, faker => faker.Person.UserName)
.Generate(10);
Estamos criando 10 usuários, utilizando o Bogus.
Agora vamos criar uma lista com e-mails validos e e-mails inválidos:
private static readonly List<string> emails =
FakeUsuarios.Select(x => x.Email)
.Concat(FakeUsuarios.Select(x => x.Login)).ToList();
Com isso teremos um total de 20 itens na lista e-mails.
Agora faremos os regex abaixo:
private static readonly Regex RegexStatico =
new(@"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase);
private static readonly Regex RegexStaticoCompilado =
new(@"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase | RegexOptions.Compiled,
TimeSpan.FromMilliseconds(250));
Com isso temos o primeiro Regex sendo estático e o segundo estático e compilado, também foi informado um timeout de 250 milissegundos. Esse timeout deve ser configurado conforme a necessidade da sua aplicação.
Agora iremos criar os métodos responsáveis pelos testes.
Importante ressaltar que todos os métodos tem a anotação de [Benchmark].
[Benchmark]
public void IsMatchInternal()
{
var regex = new Regex(@"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase);
for (var i = 0; i < emails.Count; i++)
{
var email = emails[i];
var isMatch = regex.IsMatch(email);
}
}
No método acima, estamos declarando o regex internamente e fazendo a validação de todos os e-mails da nossa lista.
[Benchmark]
public void IsMatchInternalCompiled()
{
var regex = new Regex(@"^[^@\s]+@[^@\s]+\.[^@\s]+$", RegexOptions.IgnoreCase |
RegexOptions.Compiled);
for (var i = 0; i < emails.Count; i++)
{
var email = emails[i];
var isMatch = regex.IsMatch(email);
}
}
Já no método acima, estamos declarando o regex internamente e a flag de compilado.
[Benchmark]
public void IsMatchStatic()
{
for (var i = 0; i < emails.Count; i++)
{
var email = emails[i];
var isMatch = RegexStatico.IsMatch(email);
}
}
Nesse método estamos utilizando a declaração estática RegexStatico ao invés de declararmos internamente no método.
[Benchmark]
public void IsMatchStaticCompiled()
{
for (var i = 0; i < emails.Count; i++)
{
var email = emails[i];
var isMatch = RegexStaticoCompilado.IsMatch(email);
}
}
Finalmente o último método, temos a utilização da declaração estática RegexStaticoCompilado com a flag de compilado.
Agora vamos executar nossa aplicação, é importante ressaltar que devemos executá-la em modo Release.
Após executarmos, teremos o resultado no console:
Podemos ver que o método mais performático de todos foi quando utilizamos a declaração estática com a flag de compilado, onde levou 4 microssegundos.
Já o nosso pior cenário foi quando utilizamos a declaração interna e copilada, onde levou 1.9 milissegundos e foi alocado 18KB de memória.
Com alguns ajustes simples podemos ter um ganho expressivo de performance quando estamos trabalhando com regex.
Abaixo link do código no github:
https://github.com/ouell/regex-performance
Posted on October 11, 2021
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.