Your problem is that you are including the
\s*\w+
and captures within the alternation. Move them outside and you'll find the alternations are suddenly much faster than the loops. This is because alternations containing just fixed strings can be much better optimised (using tries). With the following changes:
my $q1s = join('|', @matchwords);
my $q1 = qr/$q1s\s*\w+/;
my $q3s = join('|', @matchwords);
my $q3 = qr/($q3s)\\s*\\w+/;
and setting the benchmark count 10x larger, I get on 5.17.6:
alternation, grouping: 1 wallclock secs ( 0.58 usr + 0.00 sys = 0.5
+8 CPU) @ 1724137.93/s (n=1000000)
alternation, no grouping: 5 wallclock secs ( 4.85 usr + 0.00 sys =
+4.85 CPU) @ 206185.57/s (n=1000000)
loop, grouping: 24 wallclock secs (23.33 usr + 0.00 sys = 23.33 CPU)
+@ 42863.27/s (n=1000000)
loop, no grouping: 23 wallclock secs (22.57 usr + 0.00 sys = 22.57 CP
+U) @ 44306.60/s (n=1000000)
Dave.