Gdy grep
lub sed
są używane z opcją, --extended-regexp
a wzorzec {1,9999}
jest częścią używanego wyrażenia regularnego, wydajność tych poleceń staje się niska. Aby być bardziej zrozumiałym, poniżej zastosowano kilka testów. [1] [2]
- Względna wydajność
grep -E
,egrep
ised -E
jest prawie równa, więc tylko testy, które zostały wykonane zgrep -E
są świadczone.
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
$ grep -E '[0123456789] {1,9999}' </ dev / null > prawdziwe 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
Jaki jest powód tak znaczącej różnicy w wydajności?
time grep -E '[0-9]{1,99}' </dev/null
kontra time grep -E '[0-9]{1,9999}' </dev/null
. Nawet bez danych wejściowych drugie polecenie jest powolne (16.04). Zgodnie z oczekiwaniami, z pominięciem -E
i ucieczki {
i }
zachowuje się tak samo i zastępując -E
z -P
nie wolno (PCRE jest inny silnik). Najciekawsze jest to, jak wiele szybciej [0-9]
jest niż .
, x
a nawet [0123456789]
. Z żadnym z tych i {1,9999}
, grep
zużywa ogromną ilość pamięci RAM; Nie odważyłem się, aby działał dłużej niż ~ 10 minut.
{
}
są '
'
cytowane ; pocisk przekazuje je w niezmienionej postaci grep
. W każdym razie {1,9999}
byłoby to bardzo szybkie i proste rozszerzenie nawiasów klamrowych . Powłoka po prostu ją rozszerzy 1 9999
.
ps
i top
do sprawdzenia, czy grep
przekazano oczekiwane argumenty i czy nie bash
zużywa dużo pamięci RAM i procesora. Oczekuję grep
i sed
używam funkcji regex POSIX zaimplementowanych w libc do dopasowywania BRE / ERE; Nie powinienem tak naprawdę mówić o grep
projektowaniu, chyba że grep
programiści postanowili korzystać z tej biblioteki.
time grep ... < /dev/null
, aby ludzie nie połączyli rzeczywistego problemu z danymi, które zostały dostarczone, grep
i innymi istotami obcymi.
[0-9]+
)