Я весьма рекомендую эту статью: Regular Expression Matching Can Be Simple And Fast всем, кто интересуется программированием и компьютерными науками. У автора статьи есть, как говорят по-английски, agenda, определенная пропагандистская цель: он хочет убедить нас, что наиболее распостраненный способ распознавания регулярных выражений - путем детерминистского поиска с возвратом (backtracking) - неправильное решение, и лучше использовать более редкий метод прогона недетерминистского автомата.
Но кроме этой идеи у статьи есть самостоятельная ценность в качестве введения в теоретические основны регулярных выражений, или напоминания этих основ тем, кто когда-то знал, но некоторые подробности забыл (мне, например). Она просто очень хорошо написана, ясным языком, с отличными иллюстрациями, подробно, но не многословно. Приятно было прочитать.
Что же касается утверждения автора, он меня не убедил, но заинтриговал. Конечно, тот факт, что с некоторыми "патологическими" regexp-ами обычные методы справляются только за экспоненциальное время хорошо известен. На практике программистам приходится их избегать: переписывать по-другому, менять логику итд. Но неясно, стоит ли преимущество того, что у нас гарантированно не будет "патологических" случаев определенной потери скорости в "обычных" случаях. Интуитивно мне кажется, что такая потеря, в среднем, неизбежна. Автор старательно обходит этот вопрос стороной, предлагая измерения только одного патологического случая. Кроме того, без некоторых дополнительных возможностей, кроме собственно сравнения строки по regexp-у, современные языки не могут обойтись - например, автоматической поимки вложенных паттернов в переменные ($1, $2 итд. в Перле). Автор упоминает, что есть возможность достичь этого и в методе недетерминистского прогона, что мне кажется интересным (потому что неочевидно, как к этому подойти); постараюсь пойти по его ссылкам и разобраться в подробностях.
Мнения и комментарии, как обычно, приветствуются.
no subject
Date: 2007-01-26 03:21 pm (UTC)оффтоп
Date: 2007-01-26 03:24 pm (UTC)----- test.pl -----
#!/usr/bin/perl -w
use strict;
print $_ for ('a' .. 'я');
-------------------
работает так:
-------------------
alexx@srv:~/src/ico$ ./test.pl
abcdefghijklmnopqrstuvwxyz
-------------------
?
no subject
Date: 2007-01-26 03:45 pm (UTC)no subject
Date: 2007-01-26 03:47 pm (UTC)1. интерактивный поиск в текстовых редакторах (поскольку нехилая вероятность false positives в этом случае совершенно неважна, как и точность вообще).
2. когда нужно написать токенизатор, производительность которого реально критична.
за применения регекспов в прочих контекстах надо пороть.
no subject
Date: 2007-01-26 03:50 pm (UTC)no subject
Date: 2007-01-26 03:59 pm (UTC)no subject
Date: 2007-01-26 03:59 pm (UTC)Re: оффтоп
Date: 2007-01-26 04:02 pm (UTC)Re: оффтоп
Date: 2007-01-26 04:06 pm (UTC)==========
#!/usr/bin/perl -w
use strict;
use locale;
use POSIX qw(locale_h);
my $locale = "ru_RU.KOI8-R";
my $new_locale = setlocale(LC_ALL, $locale);
warn "Unable to set locale '$locale!' Falling to '$new_locale'" if ( $locale ne $new_locale );
print $_ for ('a' .. 'я');
==========
$ ./test.pl
abcdefghijklmnopqrstuvwxyz
no subject
Date: 2007-01-26 04:09 pm (UTC)no subject
Date: 2007-01-26 04:16 pm (UTC)no subject
Date: 2007-01-26 04:33 pm (UTC)ok
no subject
Date: 2007-01-26 04:35 pm (UTC)Я это к тому, что вообще нормальные современные движки преобразуют НКА в ДКА, оставляя, правда, по пути точки бэктрекинга, но, наверное, только в тех случаях, когда начинает экспоненциально расти размер автомата.
Ещё у автора есть забавный пассаж:
"Some might argue that this test is unfair to the backtracking implementations, since it focuses on an uncommon corner case. This argument misses the point: given a choice between an implementation with a predictable, consistent, fast running time on all inputs or one that usually runs quickly but can take years of CPU time (or more) on some inputs, the decision should be easy."
который выдаёт довольно специфический подход. Мы ж не на алгоритм сортировки смотрим, которому злодейка-реальность может скормить худший случай, тут те inputs, от которых зависит производительность, задаём лично мы.
Так вообще смешанное ощущение осталось. С одной стороны, действительно довольно странно выглядит дефолтная реализация через ДКА+бэктрекинг, заставляющая искать продукты сторонних производителей если вдруг так получилось, что нужен именно НКА (особенно что никаких проблем их совместить и дать возможность ручного или автоматического выбора, нет). С другой -- совершенно очевидно, что на непатологических случаях реализация на ДКА рвёт реализацию на НКА раз в десять, наверное.
С учётом загадочно выбранных тест-кейзов (точнее, одного тест-кейза), изобилия кода в статье и предыдущего пассажа, можно осторожно заключить, что автор, может быть, принадлежит к числу теоретических программистов, стремясь при том причинить максимальное добро нам, практическим, но ему, к счастью, никто не даёт.
И если уж бороться с чем-нибудь, так это с квиксортом в либц. Он, конечно, мерджсорт тоже по производительности в конкретных реализациях наверное делает, но зато вероятность словить худший случай неиллюзорна.
no subject
Date: 2007-01-26 04:41 pm (UTC)Поэтому иногда оставляются Специальные Вершины, инициализирующие бэктрекинг.
no subject
Date: 2007-01-26 04:44 pm (UTC)no subject
Date: 2007-01-26 04:57 pm (UTC)no subject
Date: 2007-01-26 05:06 pm (UTC)no subject
Date: 2007-01-26 05:10 pm (UTC)Я это к тому, что вообще нормальные современные движки преобразуют НКА в ДКА
Вы что-то странное говорите. "Точки бэктрекинга" - это и есть те места, где НКА раздваивается, если их "оставлять по пути", то и так налицо ДКА. "Нормальные современные движки" могут, конечно, на простых случаях все делать без бэктрекинга вообще, путем преобразования НКА в ДКА, но если у вас есть хотя бы один capture внутри, то они по-моему уже не умеют этого делать - без связи с экспоненциальным ростом числа состояний.
который выдаёт довольно специфический подход. Мы ж не на алгоритм сортировки смотрим, которому злодейка-реальность может скормить худший случай, тут те inputs, от которых зависит производительность, задаём лично мы.
В целом согласен, хотя изредка есть случаи, когда наши регэкспы формируются реальностью (нетривиальным образом).
С другой -- совершенно очевидно, что на непатологических случаях реализация на ДКА рвёт реализацию на НКА раз в десять, наверное.
Меня интересует коэффициент "раз в десять". Если десять равно двум или трем, то это необязательно важно... интуитивно кажется, что больше, но в конечном итоге это зависит от того, как много бэктрекинга (пусть даже вполне линейного по своим масштабам, но как много конкретно) делает "типичный" случай.
no subject
Date: 2007-01-26 05:11 pm (UTC)no subject
Date: 2007-01-26 05:12 pm (UTC)no subject
Date: 2007-01-26 05:37 pm (UTC)Re: оффтоп
Date: 2007-01-26 05:38 pm (UTC)no subject
Date: 2007-01-26 05:43 pm (UTC)Под этой фразой можно подразумевать многое, как я объяснил в одном из комментов выше.
Механизм Перла основан на детерминистском прогоне конечного автомата с бэктрэкингом. В такой схеме нет никакой проблемы поддерживать внутренние ссылки; в общем случае такая поддержка приведет к экспоненциальному худшему времени работы, но сам по себе бэктрэкинг уже приводит к экспоненциальному худшему времени, так что это как бы не так уж и страшно.
Проблема с внутренними ссылками в том, что если мы хотим искать регулярные выражения путем недетерминистского прогона конечного автомата, как предлагает автор статьи, то тогда любое регулярное выражение в строгом смысле этого слова работает за линейное время, но если добавить внутренние ссылки, то получается опять экспоненциальное (в худшем случае).
no subject
Date: 2007-01-26 05:48 pm (UTC)no subject
Date: 2007-01-26 05:49 pm (UTC)