#define QSORT_BREAK_EVEN 6
#endif
+/* QSORT_PLAY_SAFE is the size of the largest partition we're willing
+ to go quadratic on. We innoculate larger partitions against
+ quadratic behavior by shuffling them before sorting. This is not
+ an absolute guarantee of non-quadratic behavior, but it would take
+ staggeringly bad luck to pick extreme elements as the pivot
+ from randomized data.
+*/
+#ifndef QSORT_PLAY_SAFE
+#define QSORT_PLAY_SAFE 255
+#endif
+
/* ************************************************************* Data Types */
/* hold left and right index values of a partition waiting to be sorted (the
return;
}
+ /* Innoculate large partitions against quadratic behavior */
+ if (num_elts > QSORT_PLAY_SAFE) {
+ register size_t n, j;
+ register SV **q;
+ for (n = num_elts, q = array; n > 1; ) {
+ j = n-- * Drand01();
+ temp = q[j];
+ q[j] = q[n];
+ q[n] = temp;
+ }
+ }
+
/* Setup the initial partition definition and fall into the sorting loop
*/
part_left = 0;
gptr *small[SMALLSORT], **indir, tmp;
SVCOMPARE_t savecmp;
if (nmemb <= 1) return; /* sorted trivially */
-
+
/* Small arrays can use the stack, big ones must be allocated */
if (nmemb <= SMALLSORT) indir = small;
else { New(1799, indir, nmemb, gptr *); }
-
+
/* Copy pointers to original array elements into indirect array */
for (n = nmemb, pp = indir, q = list1; n--; ) *pp++ = q++;
-
+
savecmp = RealCmp; /* Save current comparison routine, if any */
RealCmp = cmp; /* Put comparison routine where cmpindir can find it */
-
+
/* sort, with indirection */
S_qsortsvu(aTHX_ (gptr *)indir, nmemb, cmpindir);
-
+
pp = indir;
q = list1;
for (n = nmemb; n--; ) {
RealCmp = savecmp;
}
}
-
-/*
+
+/*
=for apidoc sortsv
Sort an array. Here is an example:
- sortsv(AvARRAY(av), av_len(av)+1, Perl_sv_cmp_locale);
+ sortsv(AvARRAY(av), av_len(av)+1, Perl_sv_cmp_locale);
=cut
*/
-
+
void
Perl_sortsv(pTHX_ SV **array, size_t nmemb, SVCOMPARE_t cmp)
{
S_mergesortsv;
SV **hintsvp;
I32 hints;
-
+
if ((hints = SORTHINTS(hintsvp))) {
if (hints & HINT_SORT_QUICKSORT)
sortsvp = S_qsortsv;
sortsvp = S_mergesortsv;
}
}
-
+
sortsvp(aTHX_ array, nmemb, cmp);
}
tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
if (tmpsv) {
NV d;
-
+
if (SvIOK(tmpsv)) {
I32 i = SvIVX(tmpsv);
if (i > 0)
tryCALL_AMAGICbin(a,b,ncmp,&tmpsv);
if (tmpsv) {
NV d;
-
+
if (SvIOK(tmpsv)) {
I32 i = SvIVX(tmpsv);
if (i > 0)
tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv);
if (tmpsv) {
NV d;
-
+
if (SvIOK(tmpsv)) {
I32 i = SvIVX(tmpsv);
if (i > 0)
tryCALL_AMAGICbin(str1,str2,scmp,&tmpsv);
if (tmpsv) {
NV d;
-
+
if (SvIOK(tmpsv)) {
I32 i = SvIVX(tmpsv);
if (i > 0)