Когда 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]+)