pp_ncmp: favour the non- Perl_isnan route
authorDavid Mitchell <davem@iabyn.com>
Tue, 21 Jun 2011 16:32:20 +0000 (17:32 +0100)
committerDavid Mitchell <davem@iabyn.com>
Sat, 25 Jun 2011 08:28:17 +0000 (09:28 +0100)
Currently pp_ncmp(), when comparing two NVs, prefers to check its two args
for NaNness first, and if either of them are, then return undef.  Only if
Perl_isnan isn't defined does it fall back to doing three compares (<, >,
=) where if all three fail it returns undef.

This is in contrast to the other compare functions (e.g. pp_lt), which
only use Perl_isnan if NAN_COMPARE_BROKEN is defined - i.e. they prefer to
rely on the '<' (or whatever) test to handle NaNs implicitly.

Change pp_ncmp to favour not using Perl_isnan(). This has two advantages:

First, speed: in the normal case we replace:
    two function calls to Perl_isnan plus two comparisons,
with:
    three comparisons.

Second, this makes pp_ncmp more similar to the other comparison functions,
allowing for code reuse in the future.

pp.c

diff --git a/pp.c b/pp.c
index 2cbbfdd..997b5ba 100644 (file)
--- a/pp.c
+++ b/pp.c
@@ -2439,7 +2439,7 @@ PP(pp_ncmp)
       dPOPTOPnnrl_nomg;
       I32 value;
 
-#ifdef Perl_isnan
+#if defined(NAN_COMPARE_BROKEN) && defined(Perl_isnan)
       if (Perl_isnan(left) || Perl_isnan(right)) {
          SETs(&PL_sv_undef);
          RETURN;