[Perl/perl5] 792666: Add OPpMATCH_JUST_COUNT for when matches just need...

[email protected] (Richard Leach via perl5-changes) Mon, 27 Jul 2026 05:06:12 -0700
Newsgroups perl.perl5.changes
Message-ID <Perl/perl5/push/refs/heads/blead/[email protected]>
  Branch: refs/heads/blead
  Home:   https://github.com/Perl/perl5
  Commit: 7926662ca769828df52a5f3543ba1f4b28acaed8
      https://github.com/Perl/perl5/commit/7926662ca769828df52a5f3543ba1f4b28acaed8
  Author: Richard Leach <[email protected]>
  Date:   2026-07-27 (Mon, 27 Jul 2026)

  Changed paths:
    M lib/B/Op_private.pm
    M opcode.h
    M regen/embed.pl
    M regen/op_private

  Log Message:
  -----------
  Add OPpMATCH_JUST_COUNT for when matches just need counting

A new flag - OPpMATCH_JUST_COUNT - is set when the following
pattern of OPs, used to obtain a count of matches, is observed:

    $count = () = $str =~ /.../g

This is a common idiom for counting the number of times a regex
matches a target string. However, it pushes all matches to the
stack - creating a new SV to hold them - only for OP_AASSIGN
to just see how many SV*s there are and then discard them all.

With this new flag, subsequent commits can reduce - or eliminate -
the amount of mortal SV churn.


  Commit: b54e6f55f41a92ca9bf277176a989e1f7ebbad5b
      https://github.com/Perl/perl5/commit/b54e6f55f41a92ca9bf277176a989e1f7ebbad5b
  Author: Richard Leach <[email protected]>
  Date:   2026-07-27 (Mon, 27 Jul 2026)

  Changed paths:
    M lib/B/Deparse.pm
    M lib/B/Deparse.t
    M op.c
    M pp_hot.c

  Log Message:
  -----------
  pp_match: count matches rather than emitting for =()= $str =~ /.../g

A common idiom for counting the number of matches in a string is:

    my $count =()= $str =~ /$pat/g;

This wasn't previously special-cased, so `pp_match` would emit all
matches (or captures, depending upon `$pat`) by copying them into
new mortal SVs, only for `pp_aassign` to just calculate the number
of SVs on the stack, with the new mortals freed by the next `FREETMPS`.

With this commit, the emitted OP tree looks more like this:

    my $count = $str =~ /$pat/g;

with `pp_match` emitting only a single SV containing a final count
of how many SVs there previously _would_ have been.

`my $str = "Perl" x 50_000_000; my $count = () = $str =~ /Per/g; print $count, "\n";`
was used to measure the difference this makes.

`/usr/bin/time -v ...` showed:
* 5.43.11
```
	Maximum resident set size (kbytes): 4520208
	Minor (reclaiming a frame) page faults: 904658
```
* Now
```
	Maximum resident set size (kbytes): 200460
	Minor (reclaiming a frame) page faults: 504
```

`perf stat ...` showed:
* 5.43.11
```
	          4,953.15 msec task-clock                       #    0.962 CPUs utilized
                56      context-switches                 #   11.306 /sec
                 0      cpu-migrations                   #    0.000 /sec
           905,221      page-faults                      #  182.757 K/sec
    23,099,997,992      cycles                           #    4.664 GHz
     2,260,714,999      stalled-cycles-frontend          #    9.79% frontend cycles idle
    63,686,791,017      instructions                     #    2.76  insn per cycle
    13,292,368,507      branches                         #    2.684 G/sec
       124,086,655      branch-misses                    #    0.93% of all branches
```
* Now
```
          1,090.87 msec task-clock                       #    0.999 CPUs utilized
                 9      context-switches                 #    8.250 /sec
                 0      cpu-migrations                   #    0.000 /sec
               483      page-faults                      #  442.764 /sec
     4,937,382,721      cycles                           #    4.526 GHz
         9,767,979      stalled-cycles-frontend          #    0.20% frontend cycles idle
    21,584,781,272      instructions                     #    4.37  insn per cycle
     4,154,191,923      branches                         #    3.808 G/sec
           381,747      branch-misses                    #    0.01% of all branches
```


  Commit: 44f4945c88a0598be10ee67b689de6ff4bf84bc1
      https://github.com/Perl/perl5/commit/44f4945c88a0598be10ee67b689de6ff4bf84bc1
  Author: Richard Leach <[email protected]>
  Date:   2026-07-27 (Mon, 27 Jul 2026)

  Changed paths:
    M pod/perldelta.pod

  Log Message:
  -----------
  perldelta for optimized match count idiom [GH #24558]


Compare: https://github.com/Perl/perl5/compare/bbd6721ffa64...44f4945c88a0

To unsubscribe from these emails, change your notification settings at https://github.com/Perl/perl5/settings/notifications