sort optimization
Salvador FandiƱo [Mon, 6 Jun 2005 12:05:05 +0000 (13:05 +0100)]
Message-ID: <20050606110425.22941.qmail@lists.develooper.com>

p4raw-id: //depot/perl@24853

pp_sort.c

index b1c6226..4b3f56c 100644 (file)
--- a/pp_sort.c
+++ b/pp_sort.c
@@ -1488,6 +1488,10 @@ S_sortsv_desc(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp)
     sortsvp(aTHX_ array, nmemb, cmp, 1);
 }
 
+#define SvNSIOK(sv) ((SvFLAGS(sv) & SVf_NOK) || ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) == SVf_IOK))
+#define SvSIOK(sv) ((SvFLAGS(sv) & (SVf_IOK|SVf_IVisUV)) == SVf_IOK)
+#define SvNSIV(sv) ( SvNOK(sv) ? SvNVX(sv) : ( SvSIOK(sv) ? SvIVX(sv) : sv_2nv(sv) ) )
+
 PP(pp_sort)
 {
     dVAR; dSP; dMARK; dORIGMARK;
@@ -1507,6 +1511,7 @@ PP(pp_sort)
     U8 flags = PL_op->op_flags;
     void (*sortsvp)(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp)
       = Perl_sortsv;
+    I32 all_SIVs = 1;
 
     if (gimme != G_ARRAY) {
        SP = MARK;
@@ -1609,12 +1614,14 @@ PP(pp_sort)
                        }
                    }
                    else {
-                       if (!SvNOK(*p1)) {
+                       if (!SvNSIOK(*p1)) {
                            if (SvAMAGIC(*p1))
                                overloading = 1;
                            else
                                (void)sv_2nv(*p1);
                        }
+                       if (all_SIVs && !SvSIOK(*p1))
+                           all_SIVs = 0;
                    }
                }
                else {
@@ -1691,9 +1698,9 @@ PP(pp_sort)
            start = sorting_av ? AvARRAY(av) : ORIGMARK+1;
            sortsvp(aTHX_ start, max,
                    (priv & OPpSORT_NUMERIC)
-                       ? ( (priv & OPpSORT_INTEGER)
+                       ? ( ( ( priv & OPpSORT_INTEGER) || all_SIVs)
                            ? ( overloading ? amagic_i_ncmp : sv_i_ncmp)
-                           : ( overloading ? amagic_ncmp : sv_ncmp))
+                           : ( overloading ? amagic_ncmp : sv_ncmp ) )
                        : ( IN_LOCALE_RUNTIME
                            ? ( overloading
                                ? amagic_cmp_locale
@@ -1831,8 +1838,8 @@ sortcv_xsub(pTHX_ SV *a, SV *b)
 static I32
 sv_ncmp(pTHX_ SV *a, SV *b)
 {
-    NV nv1 = SvNV(a);
-    NV nv2 = SvNV(b);
+    NV nv1 = SvNSIV(a);
+    NV nv2 = SvNSIV(b);
     return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0;
 }