in reply to Extracting /regex/mg in a while loop

There's always a trade-off between elegance and performance and convenience. But I don't think you should be surprised that #1 is faster.

Doing a quick back-of-the-envelope estimation of them might look like:

    • Apply regex to string from pos($x), scanning for /(^A|^B)/ in performance-tuned C code
    • Update $1 and $2 (which are cheap read-only aliases) and update pos($_) and return true from regex.
    • While opcode evaluates regex return value
    • Enter loop scope
    • Run some opcodes
    • Exit loop scope
    • Perform getline on a file handle
    • Fill a read-buffer with chunks of the scalar (which ends up copying the whole scalar)
    • Update $_ with a copy read from the buffer (which probably ends up copying the whole scalar again)
    • While loop special-case evaluates true when getline succeeds
    • Enter loop scope
    • Initialize two pad variables
    • Run a regex, and execute two opcodes even if it wasn't a line you wanted
    • Perform a double assignment (maybe involves more copying)
    • Run some opcodes
    • Exit loop scope

Normally, the performance of something like this wouldn't matter much, unless you're processing really huge data, so I'd say write it whichever way is most convenient and re-usable. (like if you often process files instead of scalars already loaded in memory, then might as well leave it in a read loop) But, if you want to try some other things for performance (no promises, I'm lazy and just suggesting experiments) you could try:

print "$1 method $2\n" while $x =~ /^([AB])(.+)$/mg;
or
# always match the entire string, running your code on matching lines /^(?: (?: ([AB]) (.+) (?{ print "$1 method $2\n"; }) | .* ) \n? )*/x