[Date Prev][Date Next][Thread Prev][Thread Next] [Search] [Date Index] [Thread Index]

Re: [Fun With Perl] Another oddity from the days of assembler



On Mon, Jun 14, 1999 at 10:34:24AM +0200, Roland Giersig wrote:
> Bernie Cosell wrote:
> > 
> > this little snippet is not Perl-specific, but it is a bit tricky to
> > figure out what is going on:
> > 
> > sub s
> > {
> >     my $n = $_[0] ;
> >     my $x = 0 ;
> >     while ($n) { $n &= $n-1, $x++ ; }
> >     return $x ;
> > }
> 
> Hmm, isn't that the same as
> 
>  sub s {
>    my $b = unpack("B*", pack("L*", shift));
>    $b =~ s/0+//g;
>    return length($b);
>  }
> 
> This is probably very inefficient, compared to the original
> version, but as perl is intended to work mainly with strings...
> 
> Remember: There is more than one way to do it! ;-)
> 

sub s {
  my $b = unpack("B*", pack("L*", shift));
  $b =~ tr/1//;
}

The original is actually the slowest of the three, which isn't too
surprising with the explicit loop.  The pack/unpack/length version is
about 40% faster than the original.  The pack/unpack/tr version is
about twice as fast as the original.



#!/usr/local/bin/perl

use Benchmark;

$m = 1 << shift;  # max of range

timethese(1 << shift, {  # number of iterations
    whi => sub {
        for $n (0..$m) {
            my $x = 0;
            while ($n) { $n &= $n-1, $x++ ; }
            $x;
#           print "$n\t$x\n";
        }
    },
    len => sub {
        for $n (0..$m) {
            my $b = unpack("B*", pack("L*", $n));
            $b =~ s/0+//g;
            length($b);
#           print $n, "\t", length($b), "\n";
        }
    },
    tr_ => sub {
        for $n (0..$m) {
            my $b = unpack("B*", pack ("L*", $n));
            $b =~ tr/1//;
#           print $n, "\t", $b =~ tr/1//, "\n";
        }
    }
});
__END__


~> tmp.pl 10 10
Benchmark: timing 1024 iterations of len, tr_, whi...
       len: 61 secs (56.51 usr  0.00 sys = 56.51 cpu)
       tr_: 39 secs (37.43 usr  0.00 sys = 37.43 cpu)
       whi: 84 secs (79.02 usr  0.00 sys = 79.02 cpu)


Ronald

==== Want to unsubscribe from this list? (Don't you love us anymore?)
==== Well, if you insist... Send mail with body "unsubscribe" to
==== fwp-request@technofile.org