2013-10-27 3 views
2

Недавно я стал дружелюбно относиться к регулярным выражениям и использовал их для выполнения множества задач очень эффективно. Как и в большинстве perl, TIMTOWTDI омрачило мое мнение. Есть моменты, когда я могу использовать оператор равенства или оператор привязки. Однако существуют ли времена, когда более целесообразно использовать один над другим?Когда использовать оператор равенства по оператору привязки

Во-первых, упрощенный случай

my $name = 'Chris'; 
if ($name eq 'Chris') { print 'What a great name!'; } 
if ($name =~/^Chris$/) { print 'Yip sure is a great name; } 

Так что в данном случае это наиболее упрощенная, где с помощью равенства меньше, набрав, однако в этом упрощенном примере есть какие-либо выгоды для одного или другого.

В несколько более сложный пример

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

Итак, общее правило, если вы используете целую строку с фиксированным значением для использования оператора равенства, и если вы сопоставляете строку с шаблоном, например, строку из 5 цифр /\d{5}/, тогда используйте оператор привязки.

Неправильно использовать оператор привязки в приведенных выше примерах. Я ценю, что эти примеры просто составлены и могут не отражать реальной проблемы с жизнью. Однако это были те, о которых я думал, чтобы попытаться объяснить мой вопрос.

ответ

5

Однако в этом упрощенном примере есть какая-либо польза для того или иного.

Ну, они не эквивалентны. /^Chris$/ соответствует Chris и Chris, за которым следует новая линия.

Если вы использовали эквивалентный образец (/^Chris\z/), разница была бы производительностью. Сравнение с одной строкой будет быстрее, чем регулярное совпадение. Это также понятно.

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

+1

Поддержание работоспособности является основной проблемой здесь, ИМО. В этом конкретном случае я бы пошел с опцией «eq» в обоих случаях, поскольку он лучше передает намерение разработчика. Хотя я ценю академическую дискуссию, здесь существует реальная опасность преждевременной оптимизации. @ikegami имеет это место: оптимизируйте только тогда, когда вы являетесь свидетелем проблемы. Однако мудрые люди проводят стресс-тесты относительно рано в развитии. –

3

Я бы предположил, что немного (если вообще) лучше работать с оператором eq, потому что для регулярного выражения может потребоваться фаза компиляции, а также анализ, прежде чем приступить к его определению.

Таким образом, в случае:

if ($name eq 'Chris') { print 'What a great name!'; } 
if ($name =~/^Chris$/) { print 'Yip sure is a great name; } 

... Я бы ожидать, что первое заявление будет самым быстрым.

Во втором примере, однако, вы должны рассмотреть суммированные времена неудачных случаев, когда вы предоставили логическое ИЛИ:

if ($name eq 'Chris' || $name eq 'Christopher') { print 'What a great name!'; } 
if ($name =~ /^Chris(?:topher)?$/) { print 'Yip sure is a great name; } 

... здесь все меньше вырезать и сушат. Конечно, eq может быть быстрее, но являются двумя eq s быстрее обычного выражения, которое не должно возвращаться (в этом примере)? Я не могу быть так уверен.

Обычно вам не нужно учитывать преимущества производительности. Поэтому вы не можете утверждать, что один из них «лучше», чем другой - я обычно поощрял ясность кода в этой ситуации. Но важно понимать, что eq очень неумолимо, в то время как регулярные выражения очень гибкие - позволяют без учета регистра поиск, привязка только к началу и т. Д. Когда вы делаете , ударяет по некоторому коду, в котором скорость сравнения критическая, Я хочу сравнить.

1

Сила регулярных выражений реализуется в ее изменчивости.
Когда вы даете регулярному выражению шаблон шаблона, вы «предлагаете» результаты матча для двигателя.
Изначально это тот же C "strncmp()", и вы, как и в Perl, должны были бы делать так: $ str eq "asdf", оба являются шаблонами.

Однако вы не можете описать variablilty очень хорошо только с языком, поэтому существуют механизмы регулярного выражения.

Существует накладные расходы на «eterring» двигатель, то есть: сброс переменных, отслеживание состояния и т.д ..
Но после этого, двигатель будет опережать любую комбинацию языка конструкций вы можете
concieve из. Не немного, а огромным, огромным процентом.

+0

Poppycock. Если вы создали trie из всей возможной строки соответствия, это вызовет прикладом двигателя regex. Люди используют regex engine, потому что обычно это невозможно сделать. (Слишком много строк или слишком много хлопот для поддержания вычисленного три.) – ikegami

Смежные вопросы