qsort: remove the "switch to insertion sort" optimization because it

causes catastrophic performance for certain inputs.
This commit is contained in:
yamt 2009-06-01 06:37:40 +00:00
parent 8a29be6be3
commit 99122f39e6
1 changed files with 3 additions and 14 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: qsort.c,v 1.19 2009/01/30 23:38:44 lukem Exp $ */
/* $NetBSD: qsort.c,v 1.20 2009/06/01 06:37:40 yamt Exp $ */
/*-
* Copyright (c) 1992, 1993
@ -34,7 +34,7 @@
#if 0
static char sccsid[] = "@(#)qsort.c 8.1 (Berkeley) 6/4/93";
#else
__RCSID("$NetBSD: qsort.c,v 1.19 2009/01/30 23:38:44 lukem Exp $");
__RCSID("$NetBSD: qsort.c,v 1.20 2009/06/01 06:37:40 yamt Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@ -103,13 +103,12 @@ qsort(void *a, size_t n, size_t es,
{
char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
size_t d, r;
int swaptype, swap_cnt, cmp_result;
int swaptype, cmp_result;
_DIAGASSERT(a != NULL);
_DIAGASSERT(cmp != NULL);
loop: SWAPINIT(a, es);
swap_cnt = 0;
if (n < 7) {
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
@ -136,7 +135,6 @@ loop: SWAPINIT(a, es);
for (;;) {
while (pb <= pc && (cmp_result = cmp(pb, a)) <= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swap(pa, pb);
pa += es;
}
@ -144,7 +142,6 @@ loop: SWAPINIT(a, es);
}
while (pb <= pc && (cmp_result = cmp(pc, a)) >= 0) {
if (cmp_result == 0) {
swap_cnt = 1;
swap(pc, pd);
pd -= es;
}
@ -153,17 +150,9 @@ loop: SWAPINIT(a, es);
if (pb > pc)
break;
swap(pb, pc);
swap_cnt = 1;
pb += es;
pc -= es;
}
if (swap_cnt == 0) { /* Switch to insertion sort */
for (pm = (char *) a + es; pm < (char *) a + n * es; pm += es)
for (pl = pm; pl > (char *) a && cmp(pl - es, pl) > 0;
pl -= es)
swap(pl, pl - es);
return;
}
pn = (char *) a + n * es;
r = min(pa - (char *) a, pb - pa);