Проблема не в использовании подправил / регулярных выражений имен.Это то, что внутри регулярное выражение.Это:
[ <{<iron copper carbon>.join("||")}> ]
против
[ iron || copper || carbon ]
Следующее должно устранить разницу в скорости.Пожалуйста, попробуйте и прокомментируйте свои результаты:
my regex a { || < iron copper carbon > }
Обратите внимание на первые пробелы в < iron copper ...
, а не <iron copper ...>
.Последнее означает подправило с именем iron
с аргументами copper
и т. Д. Первое означает литерал списка "кавычек", равный , как это происходит в основном языке (хотя начальный пробел необязателен в главномязык). 1
Список соответствий можно поместить в переменную массива:
my @matchers = < iron copper carbon >;
my regex a { || @matchers }
Соответствующие элементы в @matchers
могут быть произвольными регулярными выражениями, а не просто строками:
my @matchers = / i..n /, / cop+er /, / carbon /;
my regex a { || @matchers }
Предупреждение: Вышесказанное работает, но при написании этого ответа я столкнулся и теперь столкнулся с проблемой, что @
символ будет интерполировать массив не возвращается .
как сделать subrule столь же быстрым, как и явное регулярное выражение
Дело не в том, что это явно.Речь идет о регулярном выражении , которое включает оценку во время выполнения.
Как правило, регулярные выражения P6 пишутся на своем собственном языке регулярных выражений 1 , который компилируется при компиляции-time по умолчанию.
Но язык регулярных выражений P6 включает возможность ввода кода, который затем оценивается во время выполнения (при условии, что это не опасно). 2
Это может быть полезно, но приводит к накладным расходам во время выполнения, которые иногда могут быть значительными.
(Возможно также, что у вас есть некоторые плохие алгоритмы Big O Производительность происходила в связи с использованием вами оценки во время выполнения. Если это так, она становится даже хуже, чем просто интерполяция во время выполнения, потому что тогда это проблема Big O. Я не потрудился проанализировать это, потому что лучше всего использовать полностью скомпилированныйрегулярные выражения в соответствии с моим кодом выше.)
Я также пытался использовать:
my $a=rx/ [ <{ < iron copper carbon > .join("||") }> ] /
Это все еще не избегает интерполяции во время выполнения.Эта конструкция:
<{ ... }>
интерполирует, оценивая код внутри фигурных скобок во время выполнения и затем вставляя его во внешнее регулярное выражение.
Сноски
1 «Язык» P6 на самом деле представляет собой переплетенную коллекцию DSL .
2 Если вы явно не напишите use MONKEY-SEE-NO-EVAL;
(или просто use MONKEY;
) pragma для того, чтобы взять на себя ответственность за инъекционные атаки, интерполяция регулярного выражения, содержащего введенные строки, ограничена во время компиляции, чтобы гарантировать, что инъекционные атаки невозможны, и P6 откажется запускать код, если он есть.Код, который вы написали, не подвержен атакам, поэтому компилятор позволил вам написать его, как вы это сделали, и скомпилировал код без суеты.