summaryrefslogtreecommitdiff
path: root/pp_ctl.c
diff options
context:
space:
mode:
authorJarkko Hietaniemi <jhi@iki.fi>1999-01-13 17:24:59 +0000
committerJarkko Hietaniemi <jhi@iki.fi>1999-01-13 17:24:59 +0000
commit9c007264caa0e1aed57010dc2950fe35f9d8347e (patch)
tree16b435433f6ef5875c593a2549690a2ec78ea3e9 /pp_ctl.c
parent61ae2fbf8676dafa05a9a9a710fde421f30a2071 (diff)
downloadperl-9c007264caa0e1aed57010dc2950fe35f9d8347e.tar.gz
From: Hans Mulder <hansm@icgroup.nl>
Optimize common sort routines. Thread started by the message From: Hans Mulder <hansm@icgroup.nl> Sender: owner-perl5-porters@perl.org To: perl5-porters@perl.org Subject: [Patch for 5.00554] From the Todo list: Optimize sort by { $a <=> $b Message-Id: <9901092156.AA03831@icgned.icgroup.nl> and the patch from the message From: Hans Mulder <hans@icgroup.nl> To: jhi@iki.fi Cc: perl5-porters@perl.org Subject: Re: [Patch for 5.00554] From the Todo list: Optimize sort by { $a <=> $b } Date: Wed, 13 Jan 1999 17:39:35 +0100 Message-Id: <9901131639.AA17419@icgned.icgroup.nl> p4raw-id: //depot/cfgperl@2595
Diffstat (limited to 'pp_ctl.c')
-rw-r--r--pp_ctl.c93
1 files changed, 86 insertions, 7 deletions
diff --git a/pp_ctl.c b/pp_ctl.c
index 59c571dce1..3263b341b9 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -41,6 +41,10 @@ static void save_lines _((AV *array, SV *sv));
static I32 sortcv _((SV *a, SV *b));
static void qsortsv _((SV **array, size_t num_elts, I32 (*fun)(SV *a, SV *b)));
static OP *doeval _((int gimme, OP** startop));
+static I32 sv_ncmp _((SV *a, SV *b));
+static I32 sv_i_ncmp _((SV *a, SV *b));
+static I32 amagic_ncmp _((SV *a, SV *b));
+static I32 amagic_i_ncmp _((SV *a, SV *b));
I32 amagic_cmp _((SV *str1, SV *str2));
I32 amagic_cmp_locale _((SV *str1, SV *str2));
#endif
@@ -753,6 +757,20 @@ PP(pp_mapwhile)
}
}
+STATIC I32
+sv_ncmp (SV *a, SV *b)
+{
+ double nv1 = SvNV(a);
+ double nv2 = SvNV(b);
+ return nv1 < nv2 ? -1 : nv1 > nv2 ? 1 : 0;
+}
+STATIC I32
+sv_i_ncmp (SV *a, SV *b)
+{
+ IV iv1 = SvIV(a);
+ IV iv2 = SvIV(b);
+ return iv1 < iv2 ? -1 : iv1 > iv2 ? 1 : 0;
+}
#define tryCALL_AMAGICbin(left,right,meth,svp) STMT_START { \
*svp = Nullsv; \
if (PL_amagic_generation) { \
@@ -764,6 +782,50 @@ PP(pp_mapwhile)
} \
} STMT_END
+STATIC I32
+amagic_ncmp(register SV *a, register SV *b)
+{
+ SV *tmpsv;
+ tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
+ if (tmpsv) {
+ double d;
+
+ if (SvIOK(tmpsv)) {
+ I32 i = SvIVX(tmpsv);
+ if (i > 0)
+ return 1;
+ return i? -1 : 0;
+ }
+ d = SvNV(tmpsv);
+ if (d > 0)
+ return 1;
+ return d? -1 : 0;
+ }
+ return sv_ncmp(a, b);
+}
+
+STATIC I32
+amagic_i_ncmp(register SV *a, register SV *b)
+{
+ SV *tmpsv;
+ tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
+ if (tmpsv) {
+ double d;
+
+ if (SvIOK(tmpsv)) {
+ I32 i = SvIVX(tmpsv);
+ if (i > 0)
+ return 1;
+ return i? -1 : 0;
+ }
+ d = SvNV(tmpsv);
+ if (d > 0)
+ return 1;
+ return d? -1 : 0;
+ }
+ return sv_i_ncmp(a, b);
+}
+
I32
amagic_cmp(register SV *str1, register SV *str2)
{
@@ -925,13 +987,30 @@ PP(pp_sort)
if (max > 1) {
MEXTEND(SP, 20); /* Can't afford stack realloc on signal. */
qsortsv(ORIGMARK+1, max,
- (PL_op->op_private & OPpLOCALE)
- ? ( overloading
- ? FUNC_NAME_TO_PTR(amagic_cmp_locale)
- : FUNC_NAME_TO_PTR(sv_cmp_locale))
- : ( overloading
- ? FUNC_NAME_TO_PTR(amagic_cmp)
- : FUNC_NAME_TO_PTR(sv_cmp) ));
+ (PL_op->op_private & OPpSORT_NUMERIC)
+ ? ( (PL_op->op_private & OPpSORT_INTEGER)
+ ? ( overloading
+ ? FUNC_NAME_TO_PTR(amagic_i_ncmp)
+ : FUNC_NAME_TO_PTR(sv_i_ncmp))
+ : ( overloading
+ ? FUNC_NAME_TO_PTR(amagic_ncmp)
+ : FUNC_NAME_TO_PTR(sv_ncmp)))
+ : ( (PL_op->op_private & OPpLOCALE)
+ ? ( overloading
+ ? FUNC_NAME_TO_PTR(amagic_cmp_locale)
+ : FUNC_NAME_TO_PTR(sv_cmp_locale))
+ : ( overloading
+ ? FUNC_NAME_TO_PTR(amagic_cmp)
+ : FUNC_NAME_TO_PTR(sv_cmp) )));
+ if (PL_op->op_private & OPpSORT_REVERSE) {
+ SV **p = ORIGMARK+1;
+ SV **q = ORIGMARK+max;
+ while (p < q) {
+ SV *tmp = *p;
+ *p++ = *q;
+ *q-- = tmp;
+ }
+ }
}
}
LEAVE;