in reply to Re: Identifying Overlapping Matches in Nucleotide Sequence
in thread Identifying Overlapping Matches in Nucleotide Sequence
When you mentioned the overhead of capturing and case-insensitivity, it piqued my interest, so I put together a quickie, and it shows:
$ time perl ../ex_pattern_matching.pl <GGCGATGGCGTTCTAGCGCGTAAAA> x_cap_i: 7396 x_cap: 7396 x_i: 7396 x: 7396 poz: 9202 idx: 9202 ovr_cap_i: 9202 ovr_cap: 9202 ovr_i: 9202 ovr +: 9202 Rate ovr_cap ovr poz ovr_cap_i ovr_i x_cap x_cap_i x_i + idx x ovr_cap 11.1/s -- -11% -59% -60% -62% -71% -73% -73% + -91% -92% ovr 12.4/s 12% -- -54% -55% -57% -68% -69% -70% + -90% -91% poz 26.9/s 143% 117% -- -2% -7% -31% -34% -35% + -78% -79% ovr_cap_i 27.5/s 148% 122% 2% -- -5% -29% -32% -34% + -78% -79% ovr_i 28.8/s 160% 133% 7% 5% -- -26% -29% -31% + -77% -78% x_cap 38.8/s 250% 213% 44% 41% 35% -- -4% -7% + -69% -70% x_cap_i 40.5/s 266% 227% 51% 48% 41% 4% -- -3% + -67% -69% x_i 41.6/s 275% 236% 55% 51% 44% 7% 3% -- + -66% -68% idx 123/s 1012% 895% 358% 348% 327% 217% 204% 196% + -- -6% x 131/s 1079% 955% 386% 375% 353% 237% 222% 214% + 6% -- real 0m37.721s user 0m37.656s sys 0m0.015s
The entries starting with "x" have the same problem that the OP had: the count was too low since they skip overlapping matches. The idx solution you provided was the clear winner (so long as you want correct results). I was surprised at the interaction between case insenstivity and capturing: turning on either makes it slow, but the combination isn't any slower.
Since the simple (but incorrect) match was as quick as the index solution, I tried to "fix" the overlap by using the pos function on the simple match (the poz entry), but mucking about with the pos function put poz into the realm of the other overlapping match functions.
The code:
#!env perl # # ex_pattern_matching.pl # # Check speed of capturing, case sensitivity, etc. # use strict; use warnings; use Benchmark 'cmpthese'; sub gen_data { my ($len, @alphabet) = @_; my $rv = ""; $rv .= $alphabet[@alphabet * rand] while $len > length $rv; return $rv; } sub x_cap_i { my ($str, $cnt) = @_; ++$cnt while $str =~ /(AA)/gi; return $cnt; } sub x_cap { my ($str, $cnt) = @_; ++$cnt while $str =~ /(AA)/g; return $cnt; } sub x_i { my ($str, $cnt) = @_; ++$cnt while $str =~ /AA/gi; return $cnt; } sub x { my ($str, $cnt) = @_; ++$cnt while $str =~ /AA/g; return $cnt; } sub ovr_cap_i { my ($str, $cnt) = @_; ++$cnt while $str =~ /(?=(AA))/gi; return $cnt; } sub ovr_cap { my ($str, $cnt) = @_; ++$cnt while $str =~ /(?=(AA))/g; return $cnt; } sub ovr_i { my ($str, $cnt) = @_; ++$cnt while $str =~ /(?=AA)/gi; return $cnt; } sub ovr { my ($str, $cnt) = @_; ++$cnt while $str =~ /(?=AA)/g; return $cnt; } sub idx { my ($str, $cnt) = @_; my $pos = 0; $cnt++ while $pos = 1 + index $str, 'AA', $pos; return $cnt; } sub poz { my ($str, $cnt) = @_; $cnt++, pos($str)=pos($str)-1 while $str =~ /AA/g; return $cnt; } print "<", gen_data(25, A=>C=>T=>'G'), ">\n"; my $long = gen_data(150_000, A=>C=>T=>'G'); print "x_cap_i: ", x_cap_i($long), " ", "x_cap: ", x_cap($long), " ", "x_i: ", x_i($long), " ", "x: ", x($long), "\n"; print "poz: ", poz($long), " ", "idx: ", idx($long), " ", "ovr_cap_i: ", ovr_cap_i($long), " ", "ovr_cap: ", ovr_cap($long), " ", "ovr_i: ", ovr_i($long), " ", "ovr: ", ovr($long), "\n"; $long = gen_data(1_500_000, A=>C=>T=>'G'); cmpthese(100, { "x_cap_i" => sub { return x_cap_i($long, 0) }, "x_cap" => sub { return x_cap($long, 0) }, "x_i" => sub { return x_i($long, 0) }, "x" => sub { return x($long, 0) }, "idx" => sub { return idx($long, 0) }, "ovr_cap_i" => sub { return ovr_cap_i($long, 0) }, "ovr_cap" => sub { return ovr_cap($long, 0) }, "ovr_i" => sub { return ovr_i($long, 0) }, "ovr" => sub { return ovr($long, 0) }, "poz" => sub { return poz($long, 0) }, });
...roboticus
When your only tool is a hammer, all problems look like your thumb.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^3: Identifying Overlapping Matches in Nucleotide Sequence
by kcott (Archbishop) on Oct 27, 2017 at 21:12 UTC |