summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormillert <>2017-05-17 16:58:20 +0000
committermillert <>2017-05-17 16:58:20 +0000
commitfa9ca80852b3b1ef830abad923797c4a84b10a9e (patch)
treef256f67a434b6ca737c2dab4a6baeee7e31d2e88 /src
parenta5ab3b8cdd64750c6facf4db12d4c2e6b9502424 (diff)
downloadopenbsd-fa9ca80852b3b1ef830abad923797c4a84b10a9e.tar.gz
openbsd-fa9ca80852b3b1ef830abad923797c4a84b10a9e.tar.bz2
openbsd-fa9ca80852b3b1ef830abad923797c4a84b10a9e.zip
The BSD qsort() performs tail recursion elimination on the second
side of the array being partitioned to save on stack space. Greater savings can be gained by choosing recursion for the smaller side of the partition and eliminating recursion for the larger side. This also results in a small but measurable performance gain. OK otto@ schwarze@
Diffstat (limited to 'src')
-rw-r--r--src/lib/libc/stdlib/qsort.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/src/lib/libc/stdlib/qsort.c b/src/lib/libc/stdlib/qsort.c
index f16f9d0ebf..c97979ef01 100644
--- a/src/lib/libc/stdlib/qsort.c
+++ b/src/lib/libc/stdlib/qsort.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: qsort.c,v 1.14 2017/01/04 15:20:30 millert Exp $ */ 1/* $OpenBSD: qsort.c,v 1.15 2017/05/17 16:58:20 millert Exp $ */
2/*- 2/*-
3 * Copyright (c) 1992, 1993 3 * Copyright (c) 1992, 1993
4 * The Regents of the University of California. All rights reserved. 4 * The Regents of the University of California. All rights reserved.
@@ -85,7 +85,7 @@ qsort(void *aa, size_t n, size_t es, int (*cmp)(const void *, const void *))
85{ 85{
86 char *pa, *pb, *pc, *pd, *pl, *pm, *pn; 86 char *pa, *pb, *pc, *pd, *pl, *pm, *pn;
87 int cmp_result, swaptype; 87 int cmp_result, swaptype;
88 size_t d, r; 88 size_t d, r, s;
89 char *a = aa; 89 char *a = aa;
90 90
91loop: SWAPINIT(a, es); 91loop: SWAPINIT(a, es);
@@ -139,14 +139,29 @@ loop: SWAPINIT(a, es);
139 vecswap(a, pb - r, r); 139 vecswap(a, pb - r, r);
140 r = min(pd - pc, pn - pd - es); 140 r = min(pd - pc, pn - pd - es);
141 vecswap(pb, pn - r, r); 141 vecswap(pb, pn - r, r);
142 if ((r = pb - pa) > es) 142 /*
143 qsort(a, r / es, es, cmp); 143 * To save stack space we sort the smaller side of the partition first
144 if ((r = pd - pc) > es) { 144 * using recursion and eliminate tail recursion for the larger side.
145 /* Iterate rather than recurse to save stack space */ 145 */
146 a = pn - r; 146 r = pb - pa;
147 n = r / es; 147 s = pd - pc;
148 goto loop; 148 if (r < s) {
149 /* Recurse for 1st side, iterate for 2nd side. */
150 if (s > es) {
151 if (r > es)
152 qsort(a, r / es, es, cmp);
153 a = pn - s;
154 n = s / es;
155 goto loop;
156 }
157 } else {
158 /* Recurse for 2nd side, iterate for 1st side. */
159 if (r > es) {
160 if (s > es)
161 qsort(pn - s, s / es, es, cmp);
162 n = r / es;
163 goto loop;
164 }
149 } 165 }
150/* qsort(pn - r, r / es, es, cmp);*/
151} 166}
152DEF_STRONG(qsort); 167DEF_STRONG(qsort);