diff options
author | Jarkko Hietaniemi <jhi@iki.fi> | 1999-01-13 17:24:59 +0000 |
---|---|---|
committer | Jarkko Hietaniemi <jhi@iki.fi> | 1999-01-13 17:24:59 +0000 |
commit | 9c007264caa0e1aed57010dc2950fe35f9d8347e (patch) | |
tree | 16b435433f6ef5875c593a2549690a2ec78ea3e9 /pp_ctl.c | |
parent | 61ae2fbf8676dafa05a9a9a710fde421f30a2071 (diff) | |
download | perl-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.c | 93 |
1 files changed, 86 insertions, 7 deletions
@@ -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; |