in reply to &1 is no faster than %2 when checking for oddness. Oh well.

I compared
time perl -wle '$a = $_ & 1 for 1..50_000_000'
time perl -wle '$a = $_ % 2 for 1..50_000_000'

The & 1 version is always a little faster.

Replies are listed 'Best First'.
Re^2: &1 is no faster than %2 when checking for oddness. Oh well. (range)
by tye (Sage) on Nov 16, 2006 at 06:45 UTC

    I went out to 11 digits and found that %2 was usually a lot more correct than &1, and I didn't have to do it millions of times and use a timer just to be able to notice. q-:

    - tye        

      That's just a bug. Or it should be considered one.

      Perl> use Devel::Peek;; Perl> $n = 9_999_999_998; print Dump( $n ); print $n & 1; print Dump( +$n );; SV = NV(0x1844044) at 0x19920c4 REFCNT = 1 FLAGS = (NOK,pNOK) NV = 9999999998 1 SV = PVNV(0x1985a0c) at 0x19920c4 REFCNT = 1 FLAGS = (NOK,pIOK,pNOK,IsUV) UV = 4294967295 NV = 9999999998 PV = 0

      The silent 'promotion' of the NV to an UV with data loss is very messy.

      It's also kinda schizophrenic when you consider that perl does differentiate between integer and real operations some places. Take the arbitrary and intensely annoying case of:

      Perl> $c++ for 1 .. 2**32;; [Range iterator outside integer range at (eval 7) line 1, <STDIN> line + 3.

      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.

        I don't understand. Are you asserting that it is a bug that 1e11 & 1 doesn't die (or fail in some other way)? If so, then you didn't counter my point that %2 works for a ton more cases than &1. No, %2 doesn't work on huge numbers that don't fit accurately into an NV (but does work on huge numbers when you use an appropriate format for the huge numbers) nor on Russian words nor JPEG images. And, yes, writing "2" as "1.99..." leads to surprises. Of course, &1 doesn't fair any better on these straw men.

        Or are you asserting that &1 should work directly on NVs? That'd be a non-trivial design change, so I wouldn't casually call that a "bug". If that were implemented in a way that made &1 work for detecting odd NVs, then it'd probably at least make it easier to see the speed difference between it and %2 (but then you'd be forced to use %2 anyway because it'd be trivially faster, I bet).

        I'm shocked people can spend so much effort just trying to see if there is a speed difference between the two when it so clearly obvious (because it is so hard to even see a difference) that any difference that there is doesn't matter in the slightest.

        I use %2 because 11- and 16-digit numbers are real, practical, useful things to be able to deal with right now (and I can even upgrade to some module for even bigger numbers with no changes). It is a "best practice" and most of the time works great (it always works great unless you have other problems, like using inappropriate storage for the numbers you are dealing with).

        &1 often works but has zero real advantages (the speed difference, if anyone manages to show that there even is one, is of no consequence, even in fanciful extreme situations), except for people who can't equate "even" with "divisible by two" with "has 0 remainder when divided by two" and are only comfortable with equating "even" with "has some bit unset" (in what representation?).

        Using &1 means that your code won't work when someone uses it with a perfectly valid Perl number that doesn't happen to fit in a UV. That is a real, practical disadvantage.

        /me regrets having posted this already.


        - tye