ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Arrays.sort()와 Arrays.parallelSort() 내부 알고리즘
    Java & 배경지식/기본상식 2020. 8. 9. 17:35
    반응형

    Arrays.sort()

    Arrays.sort() 알고리즘은 기본적으로 DualPivotQuicksort를 사용한다.

    이 알고리즘은 기본적으로 

    1. Insertion Sort

    2. Merge Sort

    3. Quick Sort

    위 3개의 알고리즘을 사용하는데 보통 1,2, 1,3을 섞어서 사용한다.

     

        static void sort(int[] a, int left, int right,
                         int[] work, int workBase, int workLen) {
            // Use Quicksort on small arrays
            if (right - left < QUICKSORT_THRESHOLD) {
                sort(a, left, right, true);
                return;
            }
    
            /*
             * Index run[i] is the start of i-th run
             * (ascending or descending sequence).
             */
            int[] run = new int[MAX_RUN_COUNT + 1];
            int count = 0; run[0] = left;
    
            // Check if the array is nearly sorted
            for (int k = left; k < right; run[count] = k) {
                if (a[k] < a[k + 1]) { // ascending
                    while (++k <= right && a[k - 1] <= a[k]);
                } else if (a[k] > a[k + 1]) { // descending
                    while (++k <= right && a[k - 1] >= a[k]);
                    for (int lo = run[count] - 1, hi = k; ++lo < --hi; ) {
                        int t = a[lo]; a[lo] = a[hi]; a[hi] = t;
                    }
                } else { // equal
                    for (int m = MAX_RUN_LENGTH; ++k <= right && a[k - 1] == a[k]; ) {
                        if (--m == 0) {
                            sort(a, left, right, true);
                            return;
                        }
                    }
                }
    
                /*
                 * The array is not highly structured,
                 * use Quicksort instead of merge sort.
                 */
                if (++count == MAX_RUN_COUNT) {
                    sort(a, left, right, true);
                    return;
                }
            }
    
            // Check special cases
            // Implementation note: variable "right" is increased by 1.
            if (run[count] == right++) { // The last run contains one element
                run[++count] = right;
            } else if (count == 1) { // The array is already sorted
                return;
            }
    
            // Determine alternation base for merge
            byte odd = 0;
            for (int n = 1; (n <<= 1) < count; odd ^= 1);
    
            // Use or create temporary array b for merging
            int[] b;                 // temp array; alternates with a
            int ao, bo;              // array offsets from 'left'
            int blen = right - left; // space needed for b
            if (work == null || workLen < blen || workBase + blen > work.length) {
                work = new int[blen];
                workBase = 0;
            }
            if (odd == 0) {
                System.arraycopy(a, left, work, workBase, blen);
                b = a;
                bo = 0;
                a = work;
                ao = workBase - left;
            } else {
                b = work;
                ao = 0;
                bo = workBase - left;
            }
    
            // Merging
            for (int last; count > 1; count = last) {
                for (int k = (last = 0) + 2; k <= count; k += 2) {
                    int hi = run[k], mi = run[k - 1];
                    for (int i = run[k - 2], p = i, q = mi; i < hi; ++i) {
                        if (q >= hi || p < mi && a[p + ao] <= a[q + ao]) {
                            b[i + bo] = a[p++ + ao];
                        } else {
                            b[i + bo] = a[q++ + ao];
                        }
                    }
                    run[++last] = hi;
                }
                if ((count & 1) != 0) {
                    for (int i = right, lo = run[count - 1]; --i >= lo;
                        b[i + bo] = a[i + ao]
                    );
                    run[++last] = right;
                }
                int[] t = a; a = b; b = t;
                int o = ao; ao = bo; bo = o;
            }
        }

     

     

    Tim Sort(Insertion Sort + MergeSort)

    https://d2.naver.com/helloworld/0315536

     

    DualPivotQuicksort(Insertion Sort + Quick Sort)

    https://defacto-standard.tistory.com/38

     

     

     

    Arrays.parallelSort()

    병렬 sort알고리즘은 Merge Sort알고리즘을 사용한다.

     

    Merge Sort 

    https://gmlwjd9405.github.io/2018/05/08/algorithm-merge-sort.html

     

     

     

    결론

    알고리즘을 공부해본 결과 아래와같은 결과(병렬이 오래 걸린 결과)가 나온 이유는

    Merge Sort 알고리즘은 컨텍스트 스위칭 시간이 걸리기 때문에 시간이 오래 걸린것 같다.

     

     

    참고

    https://d2.naver.com/helloworld/0315536

    https://defacto-standard.tistory.com/38

    반응형

    'Java & 배경지식 > 기본상식' 카테고리의 다른 글

    Stream 다시 공부  (0) 2021.05.02
    HTTP와 HTTPS란?  (0) 2021.03.11
    자바 개발자가 알아야하는 25가지 상식!  (1) 2020.07.19
    바이트코드 조작  (0) 2020.06.07
    클래스 로더  (0) 2020.06.07
Designed by Tistory.