in reply to using s/// as map?
in thread how can I speed up this perl??

No, and for good reason - its very slow compared to a normal solution. That "e" stands for "eval string", which is pretty sluggish, and should only be used for good reason. Compare:

use Benchmark; use strict; our $dummy = 0; our %count; my $gen = ""; foreach my $l (qw|a t c g|) { $gen .= "$l$_" for qw|a t c g|; } my @gen = split '', $gen; my %tests; foreach my $test ( qw|chain subst hash_array hash_string| ) { no strict refs; $tests{$test} = sub { *{$test}{CODE}->($gen,\@gen) } } timethese(100000, \%tests); sub chain { my ($gen,$genome) = @_; for my $i (0..$#$genome) { if (($genome->[$i] eq 'a') && ($genome->[$i+1] eq 'a')) { + ++$dummy; } elsif (($genome->[$i] eq 'a') && ($genome->[$i+1] eq 'g')) { + ++$dummy; } elsif (($genome->[$i] eq 'a') && ($genome->[$i+1] eq 'c')) { + ++$dummy; } elsif (($genome->[$i] eq 'a') && ($genome->[$i+1] eq 't')) { + ++$dummy; } elsif (($genome->[$i] eq 't') && ($genome->[$i+1] eq 'a')) { + ++$dummy; } elsif (($genome->[$i] eq 't') && ($genome->[$i+1] eq 'g')) { + ++$dummy; } elsif (($genome->[$i] eq 't') && ($genome->[$i+1] eq 'c')) { + ++$dummy; } elsif (($genome->[$i] eq 't') && ($genome->[$i+1] eq 't')) { + ++$dummy; } elsif (($genome->[$i] eq 'c') && ($genome->[$i+1] eq 'a')) { + ++$dummy; } elsif (($genome->[$i] eq 'c') && ($genome->[$i+1] eq 'g')) { + ++$dummy; } elsif (($genome->[$i] eq 'c') && ($genome->[$i+1] eq 'c')) { + ++$dummy; } elsif (($genome->[$i] eq 'c') && ($genome->[$i+1] eq 't')) { + ++$dummy; } elsif (($genome->[$i] eq 'g') && ($genome->[$i+1] eq 'a')) { + ++$dummy; } elsif (($genome->[$i] eq 'g') && ($genome->[$i+1] eq 'g')) { + ++$dummy; } elsif (($genome->[$i] eq 'g') && ($genome->[$i+1] eq 'c')) { + ++$dummy; } elsif (($genome->[$i] eq 'g') && ($genome->[$i+1] eq 't')) { + ++$dummy; } } } sub subst { my ($gen,$genome) = @_; $gen=~s/(.)(?=(.))/++$count{$1.$2} and undef/eg; } sub hash_array { my ($gen,$genome) = @_; $count { $genome -> [$_] . $genome -> [$_ + 1] } ++ for (0..$#$gen +ome); } sub hash_string { my ($gen,$genome) = @_; $count { substr($gen, $_, 2) }++ for (0..length($gen)-2); } __DATA__ Benchmark: timing 100000 iterations of chain, hash_array, hash_string, + subst... chain: 64 wallclock secs (41.09 usr + 0.00 sys = 41.09 CPU) @ 2 +433.68/s (n=100000) hash_array: 14 wallclock secs (11.24 usr + 0.00 sys = 11.24 CPU) @ 8 +896.80/s (n=100000) hash_string: 8 wallclock secs ( 6.26 usr + 0.00 sys = 6.26 CPU) @ 1 +5974.44/s (n=100000) subst: 17 wallclock secs (16.60 usr + 0.00 sys = 16.60 CPU) @ 6 +024.10/s (n=100000)

Replies are listed 'Best First'.
Re: Re: using s/// as map?
by BrowserUk (Patriarch) on Nov 24, 2003 at 23:46 UTC

    Erm. Did you post the wrong version of your code?


    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "Think for yourself!" - Abigail
    Hooray!
    Wanted!

      No? Would you care to elaborate? I just retested, and it works fine.

        Okay.

        sub chain { my ($genome,@genome) = @_; for ($i..$#genome) { ....

        Where is $i set? for $_ ( $i .. $#genome)? and 32 Uninitialised string in eq errors every loop, if the loop had a defined starting place.

        sub hash_array { my ($genome,@genome) = @_; $counts { $genome [$i] . $genome [$i + 1] } ++ for (0..$#genome); }

        Where does $i come from? <and that's only scratching the surface.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "Think for yourself!" - Abigail
        Hooray!
        Wanted!