find the first occurrence of '' # fast
walk the string to the '' # fastish
skip back to the last occurrence of 'test' # fast
walk forward to the '' again # fastish
signal success # done
####
find the first occurrence of '' # fast
walk the string to the end # fastish
skip back to the last occurrence of 'test' # fast
walk forward to end of string again # fastish
repeat last two steps for each additional occurrence of 'test'
# slow - quadratic in the number of occurrences of 'test'
(no more 'test's to try) signal failure # done
####
use strict;
use Benchmark qw/ cmpthese timethese /;
my($head, $tailg, $tailb, $test, $fill)
= ("", "", "
$head
(?:(?!$tailg).)*
$test
)
(?:(?!$tailg).)*
$tailg
}sxio;
my $trial;
for my $bool (qw/ g b /) {
my $tail = ($bool eq 'g') ? $tailg : $tailb;
for my $cut (qw/ cut uncut /) {
my $re = ($cut eq 'cut') ? $recut : $reuncut;
for my $count (1, 10, 100, 1000) {
my $str = join '', $head, $fill, $test x $count, $fill, $tail;
$trial->{"$cut$count$bool"} = sub {
die if ($bool eq 'g') ^ ($str =~ $re);
};
}
}
}
timethese(-1, $trial);
####
uncut1g: 12799.05/s
cut1g: 12799.05/s
uncut1b: 11821.50/s
cut1b: 8219.27/s
uncut10g: 11486.54/s
cut10g: 11486.54/s
uncut10b: 2559.05/s
cut10b: 7244.34/s
uncut100g: 5743.27/s
cut100g: 5743.27/s
uncut100b: 125.00/s
cut100b: 3381.13/s
uncut1000g: 956.48/s
cut1000g: 956.48/s
uncut1000b: 1.85/s
cut1000b: 532.38/s