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 /op.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 'op.c')
-rw-r--r-- | op.c | 63 |
1 files changed, 62 insertions, 1 deletions
@@ -51,6 +51,7 @@ static PADOFFSET pad_findlex _((char* name, PADOFFSET newoff, U32 seq, CV* startcv, I32 cx_ix, I32 saweval)); static OP *newDEFSVOP _((void)); static OP *new_logop _((I32 type, I32 flags, OP **firstp, OP **otherp)); +static void simplify_sort(OP *o); #endif STATIC char* @@ -5048,7 +5049,9 @@ ck_sort(OP *o) o->op_private |= OPpLOCALE; #endif - if (o->op_flags & OPf_STACKED) { + if (o->op_flags & OPf_STACKED) + simplify_sort(o); + if (o->op_flags & OPf_STACKED) { /* may have been cleared */ OP *kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */ OP *k; kid = kUNOP->op_first; /* get past rv2gv */ @@ -5089,6 +5092,64 @@ ck_sort(OP *o) return o; } +static void +simplify_sort(OP *o) +{ + register OP *kid = cLISTOPo->op_first->op_sibling; /* get past pushmark */ + OP *k; + int reversed; + if (!(o->op_flags & OPf_STACKED)) + return; + kid = kUNOP->op_first; /* get past rv2gv */ + if (kid->op_type != OP_SCOPE) + return; + kid = kLISTOP->op_last; /* get past scope */ + switch(kid->op_type) { + case OP_NCMP: + case OP_I_NCMP: + case OP_SCMP: + break; + default: + return; + } + k = kid; /* remember this node*/ + if (kBINOP->op_first->op_type != OP_RV2SV) + return; + kid = kBINOP->op_first; /* get past cmp */ + if (kUNOP->op_first->op_type != OP_GV) + return; + kid = kUNOP->op_first; /* get past rv2sv */ + if (GvSTASH(kGVOP->op_gv) != PL_curstash) + return; + if (strEQ(GvNAME(kGVOP->op_gv), "a")) + reversed = 0; + else if(strEQ(GvNAME(kGVOP->op_gv), "b")) + reversed = 1; + else + return; + kid = k; /* back to cmp */ + if (kBINOP->op_last->op_type != OP_RV2SV) + return; + kid = kBINOP->op_last; /* down to 2nd arg */ + if (kUNOP->op_first->op_type != OP_GV) + return; + kid = kUNOP->op_first; /* get past rv2sv */ + if (GvSTASH(kGVOP->op_gv) != PL_curstash + || ( reversed + ? strNE(GvNAME(kGVOP->op_gv), "a") + : strNE(GvNAME(kGVOP->op_gv), "b"))) + return; + o->op_flags &= ~(OPf_STACKED | OPf_SPECIAL); + if (reversed) + o->op_private |= OPpSORT_REVERSE; + if (k->op_type == OP_NCMP) + o->op_private |= OPpSORT_NUMERIC; + if (k->op_type == OP_I_NCMP) + o->op_private |= OPpSORT_NUMERIC | OPpSORT_INTEGER; + op_free(cLISTOPo->op_first->op_sibling); /* delete comparison block */ + cLISTOPo->op_first->op_sibling = cLISTOPo->op_last; + cLISTOPo->op_children = 1; +} OP * ck_split(OP *o) |