Коли grep
або sed
використовується з опцією, --extended-regexp
а шаблон {1,9999}
є частиною регулярного вираження, який використовується, продуктивність цих команд стає низькою. Щоб бути більш зрозумілим, нижче застосовується кілька тестів. [1] [2]
- Відносна продуктивність
grep -E
,egrep
іsed -E
майже дорівнює, тому тільки тест , які були зроблені зgrep -E
передбачені.
Тест 1
$ time grep -E '[0-9]{1,99}' < /dev/null
real 0m0.002s
Тест 2
$ time grep -E '[0-9]{1,9999}' < /dev/null
> real 0m0.494s
Тест 3
$ time grep -E '[0123456789] {1,9999}' </ dev / null > справжні 21м43.947с
Тест 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
У чому причина цієї суттєвої різниці у виконанні?
time grep -E '[0-9]{1,99}' </dev/null
проти time grep -E '[0-9]{1,9999}' </dev/null
. Навіть без введення , друга команда повільна (16.04). Як і слід було очікувати, опускаючи -E
і втечу {
і }
поводишся так само і заміну -E
з -P
негайному (PCRE є іншим двигуном). Найцікавіше, наскільки швидше [0-9]
це ніж .
, x
і навіть [0123456789]
. З будь-яким із них і {1,9999}
, grep
споживає величезну кількість оперативної пам’яті; Я не наважувався пускати його більше ~ 10 хв.
{
}
будуть '
'
вказані ; оболонка передає їх незмінним grep
. У будь-якому випадку, це {1,9999}
було б дуже швидким і простим розширенням брекетів . Оболонка просто розширить його 1 9999
.
ps
і top
для того, щоб перевірити, чи grep
були передані очікувані аргументи, і що вона, не так bash
, споживає багато оперативної пам'яті та процесора. Я очікую, grep
і sed
обидва використовують функції регулярного вираження POSIX, реалізовані в libc, для відповідності BRE / ERE; Мені не варто було б особливо говорити про grep
дизайн, за винятком тих випадків, коли grep
розробники вирішили використовувати цю бібліотеку.
time grep ... < /dev/null
, щоб люди не плутали фактичну проблему з даними, поданими grep
та іншими сторонніми речами.
[0-9]+
)