Skip to content

Commit 71c142a

Browse files
committed
regexes: speed up scanning for literal matches
if an unanchored regex (not ignoring case) starts with a literal, we now use the "index" opcode (at least on parrot) to search for the start position. Speeds up the fairly artifical benchmark nqp::x(abc, 500) ~ def ~~ /def/ by a factor of 4
1 parent 062b576 commit 71c142a

File tree

2 files changed

+17
-1
lines changed

2 files changed

+17
-1
lines changed

src/QRegex/P6Regex/Actions.nqp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -667,9 +667,21 @@ class QRegex::P6Regex::Actions is HLL::Actions {
667667
self.store_regex_nfa($code_obj, $block, QRegex::NFA.new.addnode($qast));
668668
self.alt_nfas($code_obj, $block, $qast);
669669

670+
my $scan := QAST::Regex.new( :rxtype<scan> );
671+
{
672+
my $q := $qast;
673+
if $q.rxtype eq 'concat' && $q[0] {
674+
$q := $q[0]
675+
}
676+
if $q.rxtype eq 'literal' {
677+
nqp::push($scan, $q[0]);
678+
$scan.subtype($q.subtype);
679+
}
680+
}
681+
670682
$block<orig_qast> := $qast;
671683
$qast := QAST::Regex.new( :rxtype<concat>,
672-
QAST::Regex.new( :rxtype<scan> ),
684+
$scan,
673685
$qast,
674686
($anon
675687
?? QAST::Regex.new( :rxtype<pass> )

src/vm/parrot/QAST/Compiler.nqp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,10 @@ class QAST::Compiler is HLL::Compiler {
15641564
$ops.push_pirop('goto', $scanlabel);
15651565
$ops.push($looplabel);
15661566
$ops.push_pirop('inc', %*REG<pos>);
1567+
if nqp::elems($node.list) && $node.subtype ne 'ignorecase' {
1568+
$ops.push_pirop('index', %*REG<pos>, %*REG<tgt>, self.rxescape($node[0]), %*REG<pos>);
1569+
$ops.push_pirop('eq', %*REG<pos>, -1, %*REG<fail>);
1570+
}
15671571
$ops.push_pirop('gt', %*REG<pos>, %*REG<eos>, %*REG<fail>);
15681572
$ops.push_pirop('repr_bind_attr_int', %*REG<cur>, %*REG<curclass>, '"$!from"', %*REG<pos>);
15691573
$ops.push($scanlabel);

0 commit comments

Comments
 (0)