Регулярные выражения довольно ресурсоемки по сравнению с обычными строковыми операциями. Более того, их сложность скрыта за компактным синтаксисом - на глаз, почти невозможно оценить, какой из нескольких возможных вариантов будет быстрее. Проблема осложняется различными диалектами (POSIX, Perl) и реализациями (NFA, DFA) регулярных выражений.
Есть ли возможность/инструмент вычисления количества операций, которые потребуются регулярному выражению для поиска ответа в заданной строке? В первую очередь интересуют PCRE-регулярные выражения?
Ответ
Единственное надежное средство оценки производительности нескольких регулярных выражений- фактически произвести замер времени поиска и обязательно на различных образцах текста, потому что разные образцы текста будут обработаны за разное время.
Количество шагов которое показывает regex101 имеет смысл (мое субъективное мнение) только при построении рекурсивных регулярных выражений- в них оно позволит более менее оценить эффективность рекурсии.
Сравним три регулярных выражения:
[a-z] - 33 шага https://regex101.com/r/vC5lG7/1
^[^a-z]*[a-z] - 4 шага https://regex101.com/r/vC5lG7/2
^[^a-z]*?[a-z] - 4 шага https://regex101.com/r/vC5lG7/3
Выполним простой замер времени выполнения этих выражений:
function test( $re, $text, $iters ) {
$t1 = microtime( true );
for ( $i=0; $i<$iters; $i++ ) {
$res = preg_match( $re, $text );
};
$t2 = microtime( true );
echo ($t2-$t1)."
";
};
$re1 = "/[a-z]/";
$re2 = "/^[^a-z]*[a-z]/";
$re3 = "/^[^a-z]*?[a-z]/";
$text = " a";
$iters = 50000000;
test( $re1, $text, $iters );
test( $re2, $text, $iters );
test( $re3, $text, $iters );
Результат:
9.5385589599609
9.1712720394135
9.6358540058136
Первое регулярное выражение всего на 4% медленнее второго, хотя количество шагов было 33 против 4.
Первое регулярное выражение на 1% быстрее третьего, хотя количество шагов было 33 против 4.
Выводы делайте сами.
P.S.
обязательно на различных образцах текста, потому что разные образцы текста будут обработаны за разное время
Кратко поясню.
Пример
Дан большой кусок текста где совпадение будет в конце текста. В таком тексте жадная квантификация найдет его быстрее, чем минимальная, но если совпадение будет в начале большого текста, то минимальная квантификация найдет его быстрее.
Комментариев нет:
Отправить комментарий