sub using_index { our $seq; *seq = \$_[0]; my @groups; my $pos = -1; my $start = -1; for (;;) { my $new_pos = index($seq, 'M', $pos+1); if ($new_pos < 0) { if (defined($start)) { push(@groups, [ $start, $pos ]); } last; } if ($start < 0) { $start = $new_pos; } elsif ($new_pos - $pos > 1) { push(@groups, [ $start, $pos ]); $start = $new_pos; } $pos = $new_pos; } return @groups; } #### use strict; use warnings; use Benchmark qw( cmpthese ); sub using_index { our $seq; *seq = \$_[0]; my @groups; my $pos = -1; my $start = -1; for (;;) { my $new_pos = index($seq, 'M', $pos+1); if ($new_pos < 0) { if (defined($start)) { push(@groups, [ $start, $pos ]); } last; } if ($start < 0) { $start = $new_pos; } elsif ($new_pos - $pos > 1) { push(@groups, [ $start, $pos ]); $start = $new_pos; } $pos = $new_pos; } return @groups; } sub using_regexp { our $seq; *seq = \$_[0]; my @groups; push(@groups, [ $-[0], $+[0]-1 ]) while $seq =~ /M+/g; return @groups; } { my $seq = "IIIIIMMMMMMMMMMMOOOOOOOOOOOOOOOOMMMMMMMMMMMMMIIIIIMMMMMMMMMOOOOOOOOOOOOOOMMMMMMMMMMMMMIIIMMMMMMMMMMMOOOOOOOOOOOOOOOMMMMMMMMMMMIIIIIIMMMMMMMMMMMMMOOOOOOOOOOOOOOOOOOOOOOOMMMMMMMIIIMMMMMMMMMOOOOOOOOOOOOOOOOOOOOOOOOOOOMMMMMMMIIIIMMMMMMMMMMMOOOOOOOOOOOOOOOOOOOOOMMMMMMMIIIMMMMMMMMMOOOOOOOOOOOOOOOOOOOOOOOOOMMMMMMMMMIIIMMMMMMMMMMMOOOOOOOOOOOOOOOOOMMMMMMMMI"; print("using_index\n"); print("-----------\n"); printf("%d to %d\n", @$_) foreach using_index($seq); print("\n"); print("using_regexp\n"); print("------------\n"); printf("%d to %d\n", @$_) foreach using_regexp($seq); print("\n"); cmpthese(-3, { using_index => sub { my @groups = using_index $seq; 1; }, using_regexp => sub { my @groups = using_regexp $seq; 1; }, }); } #### Rate using_index using_regexp using_index 2039/s -- -63% using_regexp 5467/s 168% --