Re: как регекспом убить производительность
От: Tonal- Россия www.promsoft.ru
Дата: 27.07.16 15:49
Оценка: 126 (4) +2
К>Недавно стековерфлоу лёг на простенькой функции, которая чистила строчку от концевых пробелов.
К>Мы же понимаем, как легко это делается регекспами: s/\s+$//
К>Беда подкралась внезапно: строка с 20тыс пробелов в середине.
А вот не нужно использовать регулярки там, где есть специализированные функции.
В любом современном языке есть функция для отрезания концевых пробелов, которая гарантированно работает быстрее, экономнее и главное корректно в любых ситуациях.

К>Движок регекспа запнулся и устроил квадратичный забег с откатами.

К>http://stackstatus.net/post/147710624694/outage-postmortem-july-20-2016
К>
К>"_____x__"
К> +++++X    - неудача, откат
К>  ++++X    - неудача, откат
К>   +++X    - неудача, откат
К>    ++X    - неудача, откат
К>     +X    - неудача, откат
К>      X    - сразу неудача, идём дальше
К>       +++ - удача, конец
К>

Простейший диалект языка регулярных выражений (РЕГ) эквивалентен детерминированному конечному автомату (ДКА).
И преобразовав РЕГ в ДКА можно проверить совпадение за линейное время.
Но, уже возможность группировки и получения значений сопоставленных групп ломает эту идилию.
Не говоря уже о ссылках на группы.

Поэтому большинство популярных реализаций использует реализацию через интерпретацию — типа расширенный НКА (недетерминированный конечный автомат).
Которая сильно более гибка (например реализации от MS, Lua, PCRE умеют описывать вложенные структуры), но улетает в экспоненту на некоторых типах регулярок и строк.
Что мы и видим на данном примере.

Есть интересный результат от 2000г — тегированный ДКА.
Описан здесь: http://laurikari.net/ville/spire2000-tnfa.pdf
Известные мне реализации на Haskell https://wiki.haskell.org/Regular_expressions#regex-tdfa и С http://laurikari.net/tre/about/
Как можно увидеть они пока что не дотягивают по плюшкам до стандартных реализаций.

Да, о реализации движков очень хорошо изложено в классической книжке «Регулярные выражения» Дж. Фридла, глава 4.
Там же описаны гибридные реализации. Например можно строить для регулярки ДКА (игнорируя некоторые навороты) и НКА. Далее ищем по строке с помощью ДКА, а имея совпадение прогоняем на нём НКА.
К сожалению, о ТДКА Фридл ни во втором, ни в 3-ем русском издании не упоминает.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.