in reply to
Efficient bit-twiddling in Perl.

G'day BrowserUk,

I tried this a few different ways. Shifting first then just ANDing the six bits seems to be faster than ANDing then shifting. About half of the time seemed to be taken with the assignments, so if you can avoid some or all of those you get additional improvements. Here's the various tests:

`#!/usr/bin/env perl
use 5.010;
use strict;
use warnings;
use Benchmark qw{cmpthese :hireswallclock};
my $n = 0x80061861;
say "and_rshift: $n => ", join(' : ', and_rshift());
say "lshift_rshift: $n => ", join(' : ', lshift_rshift());
say "mixed: $n => ", join(' : ', mixed());
say "mixed_assign: $n => ", join(' : ', mixed_assign());
say "just_shift: $n => ", join(' : ', just_shift());
cmpthese(-10, {
and_rshift => \&and_rshift,
lshift_rshift => \&lshift_rshift,
mixed => \&mixed,
mixed_assign => \&mixed_assign,
just_shift => \&just_shift,
});
sub and_rshift {
my $top14 = ( $n & 0xfffc0000 ) >> 18;
my $nxt6 = ( $n & 0x0003f000 ) >> 12;
my $mid6 = ( $n & 0x00000fc0 ) >> 6;
my $bot6 = ( $n & 0x0000003f );
return ($top14, $nxt6, $mid6, $bot6);
}
sub lshift_rshift {
my $top14 = $n >> 18;
my $nxt6 = $n << 46 >> 58;
my $mid6 = $n << 52 >> 58;
my $bot6 = $n << 58 >> 58;
return ($top14, $nxt6, $mid6, $bot6);
}
sub mixed {
return ($n >> 18, $n >> 12 & 0x3f, $n >> 6 & 0x3f, $n & 0x3f);
}
sub mixed_assign {
my $top14 = $n >> 18;
my $nxt6 = $n >> 12 & 0x3f;
my $mid6 = $n >> 6 & 0x3f;
my $bot6 = $n & 0x3f;
return ($top14, $nxt6, $mid6, $bot6);
}
sub just_shift {
return ($n >> 18, $n << 46 >> 58, $n << 52 >> 58, $n << 58 >> 58);
}
`

Output:

`$ pm_bit_twiddle.pl
and_rshift: 2147883105 => 8193 : 33 : 33 : 33
lshift_rshift: 2147883105 => 8193 : 33 : 33 : 33
mixed: 2147883105 => 8193 : 33 : 33 : 33
mixed_assign: 2147883105 => 8193 : 33 : 33 : 33
just_shift: 2147883105 => 8193 : 33 : 33 : 33
Rate and_rshift lshift_rshift mixed_assign just_shi
+ft mixed
and_rshift 1942328/s -- -7% -11% -5
+2% -53%
lshift_rshift 2088397/s 8% -- -4% -4
+8% -50%
mixed_assign 2182671/s 12% 5% -- -4
+6% -48%
just_shift 4037158/s 108% 93% 85%
+-- -3%
mixed 4163497/s 114% 99% 91%
+3% --
`