[MERGE] only copy bits of regex match string
authorDavid Mitchell <davem@iabyn.com>
Sat, 8 Sep 2012 14:42:56 +0000 (15:42 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sat, 8 Sep 2012 14:42:56 +0000 (15:42 +0100)
commit1703c1fc996f9d5943ebada0759bc5212289ae8e
tree87d9216d355c745485a442812319a421310a23b0
parent2d2826733b14efb7509c9c0c28d27bca6f31d681
parent3de645a82921698b4886d748e3a5a5ed98752f42
[MERGE] only copy bits of regex match string

When making a copy of the string being matched against (so that $1, $&
et al continue to show the correct value even if the original string is
subsequently modified), only copy that substring of the original string
needed for the capture variables, rather than copying the whole string.

This is a big win for code like

    $&;
    $_ = 'x' x 1_000_000;
    1 while /(.)/;

Also, when pessimizing if the code contains $`, $& or $', record
the presence of each variable separately, so that the determination of the
substring range is based on each variable separately. So performance-wise,

   $&; /x/

is now roughly equivalent to

   /(x)/

whereas previously it was like

   /^(.*)(x)(.*)$/

and

   $&; $'; /x/

is now roughly equivalent to

   /(x)(.*)$/

etc.

Finally, this code (when not in the presence of $& etc)

    $_ = 'x' x 1_000_000;
    1 while /(.)/;

used to skip the buffer copy for performance reasons, but suffered from $1
etc changing if the original string changed. That's now been fixed too.