Your results imply a significant savings using % instead of &, which made me wonder about them. Thank you for posting your code, I ran it myself (on a dual P3-650 running NT4 with Perl 5.6) and got:
odd_1: 2 wallclock secs ( 1.70 usr + 0.00 sys = 1.70 CPU) @ 586854.
+46/s (n=1000000)
odd_2: 3 wallclock secs ( 1.67 usr + 0.00 sys = 1.67 CPU) @ 598086.
+12/s (n=1000000)
Which implies that the two are roughly equivalent, which is what I expected. I ran a second test with this code (and the following results):
#!perl -w
use strict;
use Benchmark;
timethese( 1_000_000, {
odd_1 => sub { my $num = rand(2**31); return $num % 2 },
odd_2 => sub { my $num = rand(2**31); return $num & 2 },
})
__END__
Benchmark: timing 1000000 iterations of odd_1, odd_2...
odd_1: 3 wallclock secs ( 1.69 usr + 0.00 sys = 1.69 CPU) @ 59
+2417.06/s
(n=1000000)
odd_2: 3 wallclock secs ( 1.69 usr + 0.00 sys = 1.69 CPU) @ 59
+2417.06/s
(n=1000000)
Ok, I lied. I ran it 5 times, and that result only happened once. But the other 4 runs were also very close. Perhaps there is an optimization running, since %2 would look like "grab the bit shifted off when doing >>1". And I would be surprised if no one (from the authors of Perl on down to the folks at intel) took the time to optimize this rather common operation.
Update:
So I was thinking about this some more, and thought, "I wonder what the deparser has to say about this." Turns out, nothing. Sigh.
>perl -MO=Deparse -we "$n=1231234;print $n % 2"
$n = 1231234;
print $n % 2;
-e syntax OK
>perl -MO=Deparse -we "$n=1231234;print $n & 1"
$n = 1231234;
print $n & 1;
-e syntax OK
>perl -MO=Deparse,-p -we "$n=1231234;print $n % 2"
($n = 1231234);
print(($n % 2));
-e syntax OK
>perl -MO=Deparse,-p -we "$n=1231234;print $n & 1"
($n = 1231234);
print(($n & 1));
-e syntax OK