in reply to Re: Anyone use "xor" in conditionals?
in thread Anyone use "xor" in conditionals?

Such code irks me. It always has to perform three modulus operations, even while in 99% of the cases it doesn't have to. The Date::Leapyear code irks me too, as it tests the rare cases first. I prefer code like the following:
sub is_leap { my $year = shift; return 0 if $year % 4; return 1 if $year % 100; !($year % 400) }

That code does one modulus operation in 75% of the cases, two modules operations in 24% of the cases, and only in 1% of the cases, it does 3 modulus operations.

A benchmark shows the expected results. The code that always does three modulus operations is the slowest - the code that on averages does the least modulus operations is the fastest.

#!/usr/bin/perl use strict; use warnings; use Benchmark qw /cmpthese/; sub isleap { my ($year) = @_; return 1 if (( $year % 400 ) == 0 ); # 400's are leap return 0 if (( $year % 100 ) == 0 ); # Other centuries are not return 1 if (( $year % 4 ) == 0 ); # All other 4's are leap return 0; # Everything else is not } sub browseruk { my ($year) = @_; not $year % 4 xor $year % 100 xor $year % 400; } sub abigail { my ($year) = @_; return 0 if $year % 4; return 1 if $year % 100; !($year % 400) } cmpthese -10 => { isleap => 'my $v = isleap $_ for 1800 .. 2199', browseruk => 'my $v = browseruk $_ for 1800 .. 2199', abigail => 'my $v = abigail $_ for 1800 .. 2199', }; __END__ Benchmark: running abigail, browseruk, isleap, each for at least 10 CP +U seconds... abigail: 11 wallclock secs (10.90 usr + 0.00 sys = 10.90 CPU) @ 18 +43.58/s (n=20095) browseruk: 10 wallclock secs (10.48 usr + 0.01 sys = 10.49 CPU) @ 14 +09.82/s (n=14789) isleap: 11 wallclock secs (10.76 usr + 0.01 sys = 10.77 CPU) @ 14 +54.04/s (n=15660) Rate browseruk isleap abigail browseruk 1410/s -- -3% -24% isleap 1454/s 3% -- -21% abigail 1844/s 31% 27% --

Abigail

Replies are listed 'Best First'.
Re: Re: Anyone use "xor" in conditionals?
by BrowserUk (Patriarch) on Jul 15, 2003 at 01:15 UTC

    Ah! But if it is out and out speeed we are after then I might have offered :)

    sub buk2 { $_[0] % 4 ? 0 : $_[0] % 100 ? 1 : not $_[0] % 400; } Rate browseruk isleap abigail buk2 browseruk 82.8/s -- -40% -54% -67% isleap 138/s 67% -- -24% -45% abigail 180/s 118% 31% -- -28% buk2 251/s 203% 82% 39% --

    Examine what is said, not who speaks.
    "Efficiency is intelligent laziness." -David Dunham
    "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      And why haven't you offered this as a patch to Date::Leapyear or any of the other Date:: modules? Hmmm?!? Or, even better, offer both the pureperl and XS versions ...

      In other words, it's through these incremental improvements that modules are made as strong as they can be. That kind of code is exactly the code that belongs in modules. They're supposed to fast, commented, and full of black magic. That's why modules exist!

      ------
      We are the carpenters and bricklayers of the Information Age.

      Don't go borrowing trouble. For programmers, this means Worry only about what you need to implement.

      Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.

        Mostly cos I'd never even considered looking at, never mind using a module to determine whether a year was a leapyear or not.

        I only looked up Date::Leapyear in order to find a representative example of "the conventional way". I was only responding to the question about xor, and never gave a thought to the performance until Abigail-II (rightly) posted the benchmark.

        From there, I couldn't not rise to the challenge could I :).


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller


      I wasn't looking for the fastest solution to this particular problem. My 'solution' looked similar to the one from the Date module on purpose. I wanted to show the effect of changing the order, so I used the same style which would make it more obvious what the effect is.

      Nested ?: is of course faster than repeated statement modifiers.

      Abigail

      PS: Could you fix your sig? It doesn't seem to close its font element - replying in a textform with fontsize = 1 is very annoying.

        Hopefully, my sig. is now fixed.


        Examine what is said, not who speaks.
        "Efficiency is intelligent laziness." -David Dunham
        "When I'm working on a problem, I never think about beauty. I think only how to solve the problem. But when I have finished, if the solution is not beautiful, I know it is wrong." -Richard Buckminster Fuller