Download Reference Manual
The Developer's Library for D
About Wiki Forums Source Search Contact

Changeset 3081

Show
Ignore:
Timestamp:
01/09/08 21:29:13 (11 months ago)
Author:
sean
Message:

Added some heuristics to the sort routine to address performance issues. It now matches introSort for the "median-of-3 killer" test and matches the built-in sort for the word count test, each of which were previously the respective winners in those tests. This closes #571.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/tango/core/Array.d

    r3043 r3081  
    20132013            } 
    20142014 
    2015             void quicksort( size_t l, size_t r ) 
     2015            // NOTE: This algorithm operates on the inclusive range [l .. r]. 
     2016            void insertionSort( size_t l, size_t r ) 
     2017            { 
     2018                for( size_t i = l; i <= r; ++i ) 
     2019                { 
     2020                    size_t  j = i; 
     2021                    Elem    v = buf[i]; 
     2022 
     2023                    while( j != l && pred( v, buf[j - 1] ) ) 
     2024                    { 
     2025                        buf[j] = buf[j - 1]; 
     2026                        j--; 
     2027                    } 
     2028                    buf[j] = v; 
     2029                } 
     2030            } 
     2031 
     2032            size_t medianOf( size_t l, size_t m, size_t r ) 
     2033            { 
     2034                if( pred( buf[m], buf[l] ) ) 
     2035                { 
     2036                    if( pred( buf[r], buf[m] ) ) 
     2037                        return m; 
     2038                    else 
     2039                    { 
     2040                        if( pred( buf[r], buf[l] ) ) 
     2041                            return r; 
     2042                        else 
     2043                            return l; 
     2044                    } 
     2045                } 
     2046                else 
     2047                { 
     2048                    if( pred( buf[r], buf[m] ) ) 
     2049                    { 
     2050                        if( pred( buf[r], buf[l] ) ) 
     2051                            return l; 
     2052                        else 
     2053                            return r; 
     2054                    } 
     2055                    else 
     2056                        return m; 
     2057                } 
     2058            } 
     2059 
     2060            // NOTE: This algorithm operates on the inclusive range [l .. r]. 
     2061            void quicksort( size_t l, size_t r, size_t d ) 
    20162062            { 
    20172063                if( r <= l ) 
    20182064                    return; 
     2065 
     2066                // HEURISTIC: Use insertion sort for sufficiently small arrays. 
     2067                enum { MIN_LENGTH = 80 } 
     2068                if( r - l < MIN_LENGTH ) 
     2069                    return insertionSort( l, r ); 
     2070 
     2071                // HEURISTIC: If the recursion depth is too great, assume this 
     2072                //            is a worst-case array and fail to heap sort. 
     2073                if( d-- == 0 ) 
     2074                { 
     2075                    makeHeap( buf[l .. r+1], pred ); 
     2076                    sortHeap( buf[l .. r+1], pred ); 
     2077                    return; 
     2078                } 
     2079 
     2080                // HEURISTIC: Use the median-of-3 value as a pivot.  Swap this 
     2081                //            into r so quicksort remains untouched. 
     2082                exch( r, medianOf( l, l + (r - l) / 2, r ) ); 
    20192083 
    20202084                // This implementation of quicksort improves upon the classic 
     
    20642128                    for( size_t k = l; k < p; k++, j-- ) 
    20652129                        exch( k, j ); 
    2066                     quicksort( l, j ); 
     2130                    quicksort( l, j, d ); 
    20672131                } 
    20682132                if( ++i < q ) 
     
    20702134                    for( size_t k = r - 1; k >= q; k--, i++ ) 
    20712135                        exch( k, i ); 
    2072                     quicksort( i, r ); 
     2136                    quicksort( i, r, d ); 
    20732137                } 
    20742138            } 
    20752139 
     2140            size_t maxDepth( size_t x ) 
     2141            { 
     2142                size_t d = 0; 
     2143 
     2144                do 
     2145                { 
     2146                    ++d; 
     2147                    x /= 2; 
     2148                } while( x > 1 ); 
     2149                return d * 2; // same as "floor( log( x ) / log( 2 ) ) * 2" 
     2150            } 
     2151 
    20762152            if( buf.length > 1 ) 
    20772153            { 
    2078                 quicksort( 0, buf.length - 1 ); 
     2154                quicksort( 0, buf.length - 1, maxDepth( buf.length ) ); 
    20792155            } 
    20802156        }