This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
S_regmatch: eliminate WHILEM_A_min paren saving
authorDavid Mitchell <davem@iabyn.com>
Tue, 14 Feb 2017 17:10:34 +0000 (17:10 +0000)
committerDavid Mitchell <davem@iabyn.com>
Tue, 14 Feb 2017 17:49:58 +0000 (17:49 +0000)
commit77584140f7cbfe714083cacfa671085466e98a7b
tree0b046ae3941353d4a9d1a4d600f873d247406723
parentbb414e1295cbc3c4c2a55aaf82d832d6c8bf76ec
S_regmatch: eliminate WHILEM_A_min paren saving

In something like

    "a1b2c3d4..." =~ /(?:(\w)(\d))*..../

A WHILEM state is pushed for each iteration of the '*'. Part of this
state saving includes the previous indices for each of the captures within
the body of the thing being iterated over. So we save the following sets of
values for $1,$2:

    ()()
    (a)(1)
    (b)(2)
    (c)(3)
    (d)(4)

Then if at any point we backtrack, we can undo one or more iterations and
restore the older values of $1,$2.

However, when the match is non-greedy, as in A*?B, then on failure of B
and backtracking we attempt *more* A's rather than removing some already
matched A's. So there's never any need to save all the current paren state
for each iteration.

This eliminates a lot of per-iteration overhead for minimal WHILEMs and
makes the following run about 25% faster:

$s = ("a" x 1000);
$s =~ /^(?:(.)(.))*?[XY]/ for 1..10_000;
regexec.c
t/perf/benchmarks