Quando grep
ou sed
são usados com a opção --extended-regexp
e o padrão {1,9999}
faz parte do regexp usado, o desempenho desses comandos se torna baixo. Para ser mais claro, abaixo são aplicados alguns testes. [1] [2]
- O desempenho relativo
grep -E
,egrep
esed -E
é quase igual, portanto, apenas o teste que foram feitas comgrep -E
são fornecidos.
Teste 1
$ time grep -E '[0-9]{1,99}' < /dev/null
real 0m0.002s
Teste 2
$ time grep -E '[0-9]{1,9999}' < /dev/null
> real 0m0.494s
Teste 3
$ time grep -E '[0123456789] {1,9999}' </ dev / null > real 21m43.947s
Teste 4
$ time grep -E '[0123456789]+' < /dev/null
$ time grep -E '[0123456789]*' < /dev/null
$ time grep -E '[0123456789]{1,}' < /dev/null
$ time grep -P '[0123456789]{1,9999}' < /dev/null
real 0m0.002s
Qual o motivo dessa diferença significativa de desempenho?
time grep -E '[0-9]{1,99}' </dev/null
vs. time grep -E '[0-9]{1,9999}' </dev/null
. Mesmo sem entrada , o segundo comando é lento (em 16.04). Como esperado, omitir -E
e escapar {
e }
se comporta da mesma maneira e a substituição -E
por -P
não é lenta (PCRE é um mecanismo diferente). O mais interessante é o quanto mais rápido [0-9]
é que .
, x
e mesmo [0123456789]
. Com qualquer um desses {1,9999}
, grep
consome uma quantidade enorme de RAM; Não ousei deixá-lo funcionar por mais de ~ 10min.
{
}
estão entre '
'
aspas ; a concha os passa inalterados grep
. Enfim, {1,9999}
seria uma expansão de chave muito rápida e simples . O shell iria apenas expandi-lo para 1 9999
.
ps
e top
para verificar se grep
foram transmitidos os argumentos esperados e se ele não bash
consome muita RAM e CPU. Eu espero grep
e sed
ambos usam as funções de regex POSIX implementadas em libc para correspondência BRE / ERE; Eu realmente não deveria ter falado sobre grep
design especificamente, exceto na medida em que os grep
desenvolvedores optaram por usar essa biblioteca.
time grep ... < /dev/null
, para que as pessoas não confundam o problema real com os dados alimentados grep
e outras coisas estranhas.
[0-9]+
também)