in reply to Re: Efficient bit-twiddling in Perl.
in thread Efficient bit-twiddling in Perl.
Before doing the hard part, I looked at the speeds halfway. It is not worth pursuing.
Indeed. My initial thought for this was to use unpack, and I came up with this unholy construct:
unpack 'vccc', join'',map{ pack'b*', $_ } unpack 'a14a6a6a6', unpack ' +B32', pack 'N', $n;
Which does the job but (not unexpectedly) is an order of magnitude slower than my second attempt in the OP.
That was a pretty good saving, but whenever I have asked these type of questions in the past, someone has always come up with a better solution.
And indeed, salva has; albeit only a further 20% saving. I also tried using separate lookup tables to save a dereference to no avail:
#! perl -slw use strict; use Time::HiRes qw[ time ]; my @lookup; $#lookup = 0x3ffff; $lookup[ $_ ] = [ ( $_ & 0x3f000 ) >> 12, ( $_ & 0xfc0 ) >> 6, $_ & 0x +3f ] for 0 .. 0x3ffff; my( @nxt, @mid, @bot ); $nxt[ $_ ] = ( $_ & 0x3f000 ) >> 12, $mid[ $_ ] = ( $_ & 0xfc0 ) >> 6, $bot[ $_ ] = $_ & 0x3f for 0 .. 0x3ffff; sub stuff{ # print "@_"; } our $ITERS //= 10e6; my $n = 0x80061861; my $start = time; for ( 1 .. $ITERS ) { stuff( ( $n & 0xffc00000 ) >> 18, ( $n & 0x0003f000 ) >> 12, ( $n & 0x00000fc0 ) >> 6, ( $n & 0x0000003f ) ); } printf "Shift&and took: %.12f seconds\n", ( time() - $start ) / $ITERS +; $start = time; for ( 1 .. $ITERS ) { stuff( $n >> 18, @{ $lookup[ $n & 0x3ffff ] } ); } printf " Lookup took: %.12f seconds\n", ( time() - $start ) / $ITERS +; $start = time; for ( 1 .. $ITERS ) { my $i = $n & 0x3ffff; stuff( $n >> 18, $nxt[ $i ], $mid[ $i ], $bot[ $i ] ); } printf " Lookup2 took: %.12f seconds\n", ( time() - $start ) / $ITERS +; $start = time; for ( 1 .. $ITERS ) { stuff( unpack 'vccc', join'',map{ pack'b*', $_ } unpack 'a14a6a6a6 +', unpack 'B32', pack 'N', $n ); } printf "(un)pack took: %.12f seconds\n", ( time() - $start ) / $ITERS +; __END__ C:\test>1021064 Shift&and took: 0.000000482421 seconds Lookup took: 0.000000386419 seconds Lookup2 took: 0.000000547556 seconds (un)pack took: 0.000005933478 seconds
With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
In Section
Seekers of Perl Wisdom