Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a119c0d

Browse files
committed
Tim's revision of the previous patch. He also added some sparts to
the median-of-three code to get a few percent back.
1 parent cc20b76 commit a119c0d

1 file changed

Lines changed: 35 additions & 43 deletions

File tree

Objects/listobject.c

Lines changed: 35 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -659,8 +659,6 @@ quicksort(list, compare)
659659
PyListObject *list; /* List to sort */
660660
PyObject *compare;/* Comparison function object, or NULL for default */
661661
{
662-
int size = list->ob_size; /* Number of elements to sort */
663-
PyObject **array = list->ob_item; /* Start of array to sort */
664662
register PyObject *tmp, *pivot;
665663
register PyObject **l, **r, **p;
666664
PyObject **lo, **hi, **notp;
@@ -669,10 +667,12 @@ quicksort(list, compare)
669667
PyObject **histack[STACKSIZE];
670668

671669
/* Start out with the whole array on the work stack */
672-
lostack[0] = array;
673-
histack[0] = array+size;
670+
lostack[0] = list->ob_item;
671+
histack[0] = list->ob_item + list->ob_size;
674672
top = 1;
675673

674+
#define SETK(X,Y) if ((k = docompare(X,Y,compare,list))==CMPERROR) goto fail
675+
676676
/* Repeat until the work stack is empty */
677677
while (--top >= 0) {
678678
lo = lostack[top];
@@ -688,10 +688,7 @@ quicksort(list, compare)
688688
pivot = *r;
689689
do {
690690
p = l + ((r - l) >> 1);
691-
k = docompare(pivot, *p,
692-
compare, list);
693-
if (k == CMPERROR)
694-
return -1;
691+
SETK(pivot, *p);
695692
if (k < 0)
696693
r = p;
697694
else
@@ -708,28 +705,30 @@ quicksort(list, compare)
708705
continue;
709706
}
710707

711-
/* Choose median of first, middle and last as pivot */
708+
/* Choose median of first, middle and last as pivot;
709+
this is a simple unrolled 3-element insertion sort */
712710
l = lo; /* First */
713711
p = lo + (n>>1); /* Middle */
714712
r = hi - 1; /* Last */
715713

716-
k = docompare(*p, *l, compare, list);
717-
if (k == CMPERROR)
718-
return -1;
719-
if (k < 0)
720-
{ tmp = *p; *p = *l; *l = tmp; }
721-
722-
k = docompare(*r, *p, compare, list);
723-
if (k == CMPERROR)
724-
return -1;
725-
if (k < 0)
726-
{ tmp = *r; *r = *p; *p = tmp; }
714+
pivot = *p;
715+
SETK(pivot, *l);
716+
if (k < 0) {
717+
*p = *l;
718+
*l = pivot;
719+
}
727720

728-
k = docompare(*p, *l, compare, list);
729-
if (k == CMPERROR)
730-
return -1;
731-
if (k < 0)
732-
{ tmp = *p; *p = *l; *l = tmp; }
721+
pivot = *r;
722+
SETK(pivot, *p);
723+
if (k < 0) {
724+
*r = *p;
725+
*p = pivot; /* for consistency */
726+
SETK(pivot, *l);
727+
if (k < 0) {
728+
*p = *l;
729+
*l = pivot;
730+
}
731+
}
733732

734733
pivot = *p;
735734
l++;
@@ -741,9 +740,7 @@ quicksort(list, compare)
741740

742741
/* Move left index to element >= pivot */
743742
while (l < p) {
744-
k = docompare(*l, pivot, compare, list);
745-
if (k == CMPERROR)
746-
return -1;
743+
SETK(*l, pivot);
747744
if (k < 0)
748745
l++;
749746
else {
@@ -753,9 +750,7 @@ quicksort(list, compare)
753750
}
754751
/* Move right index to element <= pivot */
755752
while (r > p) {
756-
k = docompare(pivot, *r, compare, list);
757-
if (k == CMPERROR)
758-
return -1;
753+
SETK(pivot, *r);
759754
if (k < 0)
760755
r--;
761756
else {
@@ -780,9 +775,9 @@ quicksort(list, compare)
780775
/* One (exactly) of the pointers is at p */
781776
/* assert (p == l) ^ (p == r) */
782777
notp = lisp ? r : l;
778+
*p = *notp;
783779
k = (r - l) >> 1;
784780
if (k) {
785-
*p = *notp;
786781
if (lisp) {
787782
p = r - k;
788783
l++;
@@ -791,14 +786,12 @@ quicksort(list, compare)
791786
p = l + k;
792787
r--;
793788
}
794-
/* assert l < p < r */
795789
*notp = *p;
796790
*p = pivot; /* for consistency */
797791
continue;
798792
}
799793

800794
/* assert l+1 == r */
801-
*p = *notp;
802795
*notp = pivot;
803796
p = notp;
804797
break;
@@ -818,9 +811,7 @@ quicksort(list, compare)
818811
* This wastes a compare if it fails, but can win big
819812
* when there are runs of duplicates.
820813
*/
821-
k = docompare(pivot, *l, compare, list);
822-
if (k == CMPERROR)
823-
return -1;
814+
SETK(pivot, *l);
824815
if (!(k < 0)) {
825816
/* Now extend as far as possible (around p) so that:
826817
All in [lo,r) are <= pivot
@@ -831,9 +822,7 @@ quicksort(list, compare)
831822
*/
832823
while (r > lo) {
833824
/* because r-1 < p, *(r-1) <= pivot is known */
834-
k = docompare(*(r-1), pivot, compare, list);
835-
if (k == CMPERROR)
836-
return -1;
825+
SETK(*(r-1), pivot);
837826
if (k < 0)
838827
break;
839828
/* <= and not < implies == */
@@ -843,9 +832,7 @@ quicksort(list, compare)
843832
l++;
844833
while (l < hi) {
845834
/* because l > p, pivot <= *l is known */
846-
k = docompare(pivot, *l, compare, list);
847-
if (k == CMPERROR)
848-
return -1;
835+
SETK(pivot, *l);
849836
if (k < 0)
850837
break;
851838
/* <= and not < implies == */
@@ -873,6 +860,11 @@ quicksort(list, compare)
873860

874861
/* Success */
875862
return 0;
863+
864+
fail:
865+
return -1;
866+
867+
#undef SETK
876868
}
877869

878870
static PyObject *

0 commit comments

Comments
 (0)