Compilação e reutilização em expressões regulares
É possível otimizar o desempenho de aplicativos que fazem uso extensivo de expressões regulares compreendendo como o mecanismo de expressões regulares compila expressões e como as expressões regulares são armazenadas em cache. Este artigo discute a compilação, a geração da origem e o armazenamento em cache de expressões regulares compiladas.
Expressões regulares interpretadas
Por padrão, o mecanismo de expressão regular compila uma expressão regular em uma sequência de instruções internas (esses são códigos de alto nível que são diferentes da Common Intermediate Language, ou CIL). Quando o mecanismo executa uma expressão regular, ele interpreta os códigos internos.
Expressões regulares compiladas
Se um objeto Regex for construído com a opção RegexOptions.Compiled, ele compilará a expressão regular em código CIL explícito em vez de instruções internas de expressão regular de alto nível. Isso permite que o compilador JIT (just-in-time) do .NET converta a expressão para um código de computador nativo para um melhor desempenho. O custo da construção do objeto Regex pode ser maior, mas o custo de executar correspondências com ele provavelmente é muito menor.
Expressões regulares geradas pela origem
A geração da origem para expressões regulares está disponível no .NET 7 e em versões posteriores. O gerador de origem emite, como código C#, uma implementação personalizada derivada de Regex
com lógica semelhante à que RegexOptions.Compiled
emite em IL. Você obtém todos os benefícios de desempenho de taxa de transferência de RegexOptions.Compiled
e os benefícios de inicialização de Regex.CompileToAssembly
, mas sem a complexidade de CompileToAssembly
. A origem emitida faz parte do seu projeto, o que significa que ele também é facilmente acessível e depurável.
Sempre que possível, use expressões regulares geradas na origem em vez de compilar expressões regulares usando a opção RegexOptions.Compiled. Para obter mais informações sobre expressões regulares geradas na fonte, consulte Geradores de origem de expressões regulares do .NET.
O cache de expressões regulares
Para melhorar o desempenho, o mecanismo de expressões regulares mantém um cache em todo o aplicativo com as expressões regulares compiladas. O cache armazena padrões de expressões regulares que são usados somente em chamadas de método estático. (Os padrões de expressões regulares fornecidos aos métodos de instância não são armazenados em cache.) O armazenamento em cache evita a necessidade de analisar uma expressão em código de bytes de alto nível sempre que ela for usada.
O número máximo de expressões regulares em cache é determinado pelo valor da propriedade static
(Shared
no Visual Basic) Regex.CacheSize. Por padrão, o mecanismo de expressões regulares armazena em cache até 15 expressões regulares compiladas. Se o número de expressões regulares compiladas ultrapassar o tamanho do cache, a expressão regular menos utilizada recentemente será descartada e a nova expressão regular será armazenada em cache.
Seu aplicativo pode aproveitar expressões regulares pré-compiladas de uma das duas maneiras a seguir:
- Usando um método estático do objeto Regex para definir a expressão regular. Se você estiver usando um padrão de expressão regular já definido em outra chamada de método estático, o mecanismo de expressões regulares o recuperará do cache. Caso contrário, o mecanismo compilará a expressão regular e a adicionará ao cache.
- Reutilizando um objeto Regex existente enquanto o padrão de expressão regular for necessário.
Devido à sobrecarga de instanciação de objetos e compilação de expressões regulares, criar e destruir rapidamente vários objetos Regex é um processo caro. Para aplicativos que usam um grande número de expressões regulares diferentes, você pode otimizar o desempenho usando chamadas para métodos Regex
estáticos e, possivelmente, aumentando o tamanho do cache de expressão regular.