When you reduce the overhead of the function calls (by doing the work you actually time in a tight loop), you might get other numbers
#!/pro/bin/perl -slw
use 5.016;
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, $nxt6, $mid6, $bot6);
for (1..10000) {
$top14 = ($n & 0xfffc0000) >> 18;
$nxt6 = ($n & 0x0003f000) >> 12;
$mid6 = ($n & 0x00000fc0) >> 6;
$bot6 = ($n & 0x0000003f);
}
return ($top14, $nxt6, $mid6, $bot6);
}
sub lshift_rshift
{
my ($top14, $nxt6, $mid6, $bot6);
for (1..10000) {
$top14 = $n >> 18;
$nxt6 = $n << 46 >> 58;
$mid6 = $n << 52 >> 58;
$bot6 = $n << 58 >> 58;
}
return ($top14, $nxt6, $mid6, $bot6);
}
sub mixed
{
my ($top14, $nxt6, $mid6, $bot6);
for (1..10000) {
($top14, $nxt6, $mid6, $bot6) =
($n >> 18, $n >> 12 & 0x3f, $n >> 6 & 0x3f, $n & 0x3f);
}
return ($top14, $nxt6, $mid6, $bot6);
}
sub mixed_assign
{
my ($top14, $nxt6, $mid6, $bot6);
for (1..10000) {
$top14 = $n >> 18;
$nxt6 = $n >> 12 & 0x3f;
$mid6 = $n >> 6 & 0x3f;
$bot6 = $n & 0x3f;
}
return ($top14, $nxt6, $mid6, $bot6);
}
sub just_shift
{
my ($top14, $nxt6, $mid6, $bot6);
for (1..10000) {
($top14, $nxt6, $mid6, $bot6) =
($n >> 18, $n << 46 >> 58, $n << 52 >> 58, $n << 58 >> 58)
+;
}
return ($top14, $nxt6, $mid6, $bot6);
}