Как делает qr/STRING/оператор в Perl, решают, скомпилировать ли СТРОКУ?

Ответ на Ваш самый последний вопрос: Если профилировщик не говорит Вам, что Вы проводите смешное количество времени в instanceof: Да, Вы придираетесь к мелочам.

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

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

И в истинном духе этого ответа (которому я от чистого сердца верю): Я абсолютно не знаю, как instanceof и == имеют отношение, как только компилятор монеты в пять центов получил шанс оптимизировать его.

я забыл: Никогда не измеряйте первый показ.

15
задан FMc 2 December 2009 в 15:38
поделиться

3 ответа

Часть документации "возможно компилирует", вероятно, относится к ситуациям, подобным показанной ниже, где аргумент qr // является уже скомпилированным регулярным выражением:

use re 'debug';

$re1 = qr/foo/;
$re2 = qr/$re1/;

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

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

13
ответ дан 1 December 2019 в 04:17
поделиться

Изменить: этот ответ неверен (или, по крайней мере, неверен), но в комментариях есть интересное обсуждение, которое стоит сохранить. Ответ Джона Сиракузы кажется правильным.


В документации для qr // указано, что

STRING интерполируется так же, как ШАБЛОН в m / PATTERN /.

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

foreach my $char ('a' .. 'z') {
    my $vowel = qr/[aeiou]/;
    say "$char is a vowel" if $char =~ $vowel;
}
2
ответ дан 1 December 2019 в 04:17
поделиться

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

IIRC он предназначен для обработки этого сценария:

while (my $foo = $something->next) {
     my $regex1 = qr/ab(cd+)ef?/; # only compiled once
     my $regex2 = qr/ab${foo}*ef/; # compiled every time through the loop
     # do stuff with $regex1 and $regex2
}
1
ответ дан 1 December 2019 в 04:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: