use strict; use warnings; use feature 'say'; use Time::HiRes 'time'; say $^V; my $s = '*' x 5_000_000; $s .= "0123456789 01234 n \n" x 40_000; my $re = qr/ (\d{10}) \x{20} (\d{5}) \x{20} (\w) \s\s /x; my ( $xref, $t ); # (1) peel off entry by entry $xref = substr $s, 5_000_000; # from shorter string $t = time; for ( 0 .. 39_999 ) { my $entry = substr $xref, $_ * 20, 20; die unless $entry =~ / \A $re /x; # do something useful with captures } say time - $t; $xref = substr $s, 5_000_000; # (2) global match (shorter string) $t = time; for ( 0 .. 39_999 ) { die unless $xref =~ / \G $re /gx; } say time - $t; # (3) global match (original string), pos( $s ) = 5_000_000; # start from pos $t = time; for ( 0 .. 39_999 ) { die unless $s =~ / \G $re /gx; } say time - $t; $xref = \substr $s, 5_000_000; # (4) use reference to substr $t = time; for ( 0 .. 39_999 ) { die unless $$xref =~ / \G $re /gx; } say time - $t; __END__ v5.40.0 0.0973920822143555 0.04703688621521 0.0475959777832031 3.08383107185364