Коли 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]+)