Lorsque grep
ou sed
sont utilisés avec l'option --extended-regexp
et que le modèle {1,9999}
fait partie de l'expression rationnelle utilisée, les performances de ces commandes deviennent faibles. Pour être plus clair, ci-dessous sont appliqués quelques tests. [1] [2]
- La performance relative des
grep -E
,egrep
etsed -E
est à peu près égale, de sorte que le test qui ont été faites avecgrep -E
sont fournis.
Test 1
$ time grep -E '[0-9]{1,99}' < /dev/null
real 0m0.002s
Test 2
$ time grep -E '[0-9]{1,9999}' < /dev/null
> real 0m0.494s
Test 3
$ time grep -E '[0123456789] {1,9999}' </ dev / null > vrai 21m43.947s
Test 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
Quelle est la raison de cette différence significative de performance?
time grep -E '[0-9]{1,99}' </dev/null
contre time grep -E '[0-9]{1,9999}' </dev/null
. Même sans entrée , la deuxième commande est lente (le 16.04). Comme prévu, omettre -E
et s'échapper {
et }
se comporte de la même manière et le remplacer -E
par -P
n'est pas lent (PCRE est un moteur différent). Le plus intéressant est combien plus rapide [0-9]
est que .
, x
et même [0123456789]
. Avec l'un de ceux-ci et {1,9999}
, grep
consomme une énorme quantité de RAM; Je n'ai pas osé le laisser fonctionner pendant plus de ~ 10min.
{
}
sont '
'
cités ; l'obus les passe inchangés grep
. Quoi qu'il en soit, ce {1,9999}
serait une expansion d'accolade très rapide et simple . Le shell ne ferait que l'étendre 1 9999
.
ps
et top
pour vérifier que grep
les arguments attendus étaient passés et que cela ne bash
consommait pas beaucoup de RAM et de CPU. J'attends grep
et les sed
deux utilisent les fonctions d'expression régulière POSIX implémentées dans libc pour la correspondance BRE / ERE; Je n'aurais pas vraiment dû parler de grep
design spécifiquement, sauf dans la mesure où les grep
développeurs ont choisi d'utiliser cette bibliothèque.
time grep ... < /dev/null
, afin que les gens ne confondent pas le problème réel avec les données alimentées grep
et d'autres choses étrangères.
[0-9]+
)