 |
Changeset 3081
- 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
| r3043 |
r3081 |
|
| 2013 | 2013 | } |
|---|
| 2014 | 2014 | |
|---|
| 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 ) |
|---|
| 2016 | 2062 | { |
|---|
| 2017 | 2063 | if( r <= l ) |
|---|
| 2018 | 2064 | 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 ) ); |
|---|
| 2019 | 2083 | |
|---|
| 2020 | 2084 | // This implementation of quicksort improves upon the classic |
|---|
| … | … | |
| 2064 | 2128 | for( size_t k = l; k < p; k++, j-- ) |
|---|
| 2065 | 2129 | exch( k, j ); |
|---|
| 2066 | | quicksort( l, j ); |
|---|
| | 2130 | quicksort( l, j, d ); |
|---|
| 2067 | 2131 | } |
|---|
| 2068 | 2132 | if( ++i < q ) |
|---|
| … | … | |
| 2070 | 2134 | for( size_t k = r - 1; k >= q; k--, i++ ) |
|---|
| 2071 | 2135 | exch( k, i ); |
|---|
| 2072 | | quicksort( i, r ); |
|---|
| | 2136 | quicksort( i, r, d ); |
|---|
| 2073 | 2137 | } |
|---|
| 2074 | 2138 | } |
|---|
| 2075 | 2139 | |
|---|
| | 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 | |
|---|
| 2076 | 2152 | if( buf.length > 1 ) |
|---|
| 2077 | 2153 | { |
|---|
| 2078 | | quicksort( 0, buf.length - 1 ); |
|---|
| | 2154 | quicksort( 0, buf.length - 1, maxDepth( buf.length ) ); |
|---|
| 2079 | 2155 | } |
|---|
| 2080 | 2156 | } |
|---|
Download in other formats:
|
 |
 |
|
 |
Copyright © 2006-2008 Tango. All Rights Reserved. | Page Width:
Static or
Dynamic