Эффективность и ресурсозатратность регулярных выражений

Здравствуйте. Посоветуйте пожалуйста литературу на тему того, насколько эффективны регулярные выражения как средство, какие ресурсы они потребляют и что с ними делать, чтобы выжать максимум эффективности, то есть оптимизировать, чтобы не перегружать оперативку устройства

44

Самое полезное, что можно прочитать про регулярные выражения, это вот эту вот цитату за авторством Jamie Zawinski:

Some people, when confronted with a problem, think “I know, I'll use regular expressions.” Now they have two problems.

Можно распечатать и повесить на стену. Контекст цитаты — времена, когда регулярные выражения были на пике популярности, и Perl был в большом почёте. Тогда было написано совершенно лютое количество абсолютно нечитаемого и полного багов говнокода с монстроузными выражениями в несколько строчек длиной, который было проще выкинуть и переписать по-человечески, чем пытаться сопровождать.

Если у тебя действительно есть задача, где вроде бы неудобно писать обычный код (т.е. ты делаешь что-то сложнее, чем проверку в духе "а есть ли в строчке символ @"), и в то же самое время не пытаешься решить с помощью регулярных выражений то, для чего по-хорошему надо бы написать нормальный парсер, то:

1. Пиши.
2. Замеряй производительность.

Время выполнения может быть сложно-предсказуемым, и тяжело "угадать", какой случай может оказаться для библиотеки совсем ужасным, а какой будет работать быстро.

В целом есть куча бенчмарков, и можно посмотреть, какие библиотеки в целом обычно быстрые или в целом обычно медленные. Например все имплементации std::regex — это абсолютное беспросветное говнище, работающее раз так в 300 медленнее, чем надо (и это теперь не могут починить не ломая ABI, поэтому регулярные выражения из стандартной библиотеки C++ лучше просто никогда не трогать).

Например прикрепил табличку вот отсюда: https://github.com/HFTrader/regex-performance

Смотри, например, колонку rust_regex: в сотни раз быстрее std::regex почти везде, но работает совершенно чудовищно в одном конкретном случае, где все остальные справляются гораздо лучше.

Или pcre-jit — кажется, что в целом неплохо и без больших просадок, но иногда оказывается медленней rust_regex в несколько раз.

Я это к тому, что любая попытка угадывать производительность без измерений — очень плохая затея. Ну т.е. понятно, что если сделать выражение сильно сложнее, то наверное может быть будет медленней, но сложно сказать, на 5% будет медленней или в 100 раз.

Если тебе хочется предсказуемое поведение, и у тебя крайне мало мест, где ты хотел написать регексп, то возможно там лучше написать обычный код.

5
Ответить

Спасибо, очень развернутый ответ, это круто

Ответить