--- old/src/java.base/share/classes/java/util/Arrays.java 2018-01-18 06:09:08.718759856 -0800 +++ new/src/java.base/share/classes/java/util/Arrays.java 2018-01-18 06:09:08.364727004 -0800 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -63,7 +63,7 @@ * a MergeSort, but it does have to be stable.) * *

This class is a member of the - * + * * Java Collections Framework. * * @author Josh Bloch @@ -73,41 +73,10 @@ */ public class Arrays { - /** - * The minimum array length below which a parallel sorting - * algorithm will not further partition the sorting task. Using - * smaller sizes typically results in memory contention across - * tasks that makes parallel speedups unlikely. - */ - private static final int MIN_ARRAY_SORT_GRAN = 1 << 13; - // Suppresses default constructor, ensuring non-instantiability. private Arrays() {} /** - * A comparator that implements the natural ordering of a group of - * mutually comparable elements. May be used when a supplied - * comparator is null. To simplify code-sharing within underlying - * implementations, the compare method only declares type Object - * for its second argument. - * - * Arrays class implementor's note: It is an empirical matter - * whether ComparableTimSort offers any performance benefit over - * TimSort used with this comparator. If not, you are better off - * deleting or bypassing ComparableTimSort. There is currently no - * empirical case for separating them for parallel sorting, so all - * public Object parallelSort methods use the same comparator - * based implementation. - */ - static final class NaturalOrder implements Comparator { - @SuppressWarnings("unchecked") - public int compare(Object first, Object second) { - return ((Comparable)first).compareTo(second); - } - static final NaturalOrder INSTANCE = new NaturalOrder(); - } - - /** * Checks that {@code fromIndex} and {@code toIndex} are in * the range and throws an exception if they aren't. */ @@ -124,9 +93,15 @@ } } + /** + * This flag allows system to run sorting in parallel. + */ + private static final boolean RUN_IN_PARALLEL = + Runtime.getRuntime().availableProcessors() > 1; + /* * Sorting methods. Note that all public "sort" methods take the - * same form: Performing argument checks if necessary, and then + * same form: performing argument checks if necessary, and then * expanding arguments into those required for the internal * implementation methods residing in other package-private * classes (except for legacyMergeSort, included in this class). @@ -135,16 +110,15 @@ /** * Sorts the specified array into ascending numerical order. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ public static void sort(int[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -153,10 +127,9 @@ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, * the range to be sorted is empty. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -169,22 +142,21 @@ */ public static void sort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ public static void sort(long[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -193,10 +165,9 @@ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, * the range to be sorted is empty. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -209,22 +180,21 @@ */ public static void sort(long[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ - public static void sort(short[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + public static void sort(byte[] a) { + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -233,10 +203,9 @@ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, * the range to be sorted is empty. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -247,24 +216,23 @@ * @throws ArrayIndexOutOfBoundsException * if {@code fromIndex < 0} or {@code toIndex > a.length} */ - public static void sort(short[] a, int fromIndex, int toIndex) { + public static void sort(byte[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ public static void sort(char[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -273,10 +241,9 @@ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, * the range to be sorted is empty. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -289,22 +256,21 @@ */ public static void sort(char[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ - public static void sort(byte[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1); + public static void sort(short[] a) { + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -313,10 +279,9 @@ * the index {@code toIndex}, exclusive. If {@code fromIndex == toIndex}, * the range to be sorted is empty. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -327,9 +292,9 @@ * @throws ArrayIndexOutOfBoundsException * if {@code fromIndex < 0} or {@code toIndex > a.length} */ - public static void sort(byte[] a, int fromIndex, int toIndex) { + public static void sort(short[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** @@ -343,16 +308,15 @@ * {@code 0.0f} and {@code Float.NaN} is considered greater than any * other value and all {@code Float.NaN} values are considered equal. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ public static void sort(float[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -369,10 +333,9 @@ * {@code 0.0f} and {@code Float.NaN} is considered greater than any * other value and all {@code Float.NaN} values are considered equal. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -385,7 +348,7 @@ */ public static void sort(float[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** @@ -399,16 +362,15 @@ * {@code 0.0d} and {@code Double.NaN} is considered greater than any * other value and all {@code Double.NaN} values are considered equal. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted */ public static void sort(double[] a) { - DualPivotQuicksort.sort(a, 0, a.length - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, 0, a.length); } /** @@ -425,10 +387,9 @@ * {@code 0.0d} and {@code Double.NaN} is considered greater than any * other value and all {@code Double.NaN} values are considered equal. * - *

Implementation note: The sorting algorithm is a Dual-Pivot Quicksort - * by Vladimir Yaroslavskiy, Jon Bentley, and Joshua Bloch. This algorithm - * offers O(n log(n)) performance on many data sets that cause other - * quicksorts to degrade to quadratic performance, and is typically + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted @@ -441,37 +402,23 @@ */ public static void sort(double[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); + DualPivotQuicksort.sort(a, false, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(byte[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(byte[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ - public static void parallelSort(byte[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1); - else - new ArraysParallelSortHelpers.FJByte.Sorter - (null, a, new byte[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + public static void parallelSort(int[] a) { + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -480,16 +427,10 @@ * inclusive, to the index {@code toIndex}, exclusive. If * {@code fromIndex == toIndex}, the range to be sorted is empty. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(byte[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(byte[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -501,47 +442,25 @@ * * @since 1.8 */ - public static void parallelSort(byte[] a, int fromIndex, int toIndex) { + public static void parallelSort(int[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1); - else - new ArraysParallelSortHelpers.FJByte.Sorter - (null, a, new byte[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(char[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(char[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ - public static void parallelSort(char[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJChar.Sorter - (null, a, new char[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + public static void parallelSort(long[] a) { + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -550,16 +469,10 @@ * inclusive, to the index {@code toIndex}, exclusive. If * {@code fromIndex == toIndex}, the range to be sorted is empty. * - @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(char[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(char[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -571,47 +484,25 @@ * * @since 1.8 */ - public static void parallelSort(char[] a, int fromIndex, int toIndex) { + public static void parallelSort(long[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJChar.Sorter - (null, a, new char[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(short[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(short[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ - public static void parallelSort(short[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJShort.Sorter - (null, a, new short[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + public static void parallelSort(byte[] a) { + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -620,16 +511,10 @@ * inclusive, to the index {@code toIndex}, exclusive. If * {@code fromIndex == toIndex}, the range to be sorted is empty. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(short[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(short[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -641,47 +526,25 @@ * * @since 1.8 */ - public static void parallelSort(short[] a, int fromIndex, int toIndex) { + public static void parallelSort(byte[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJShort.Sorter - (null, a, new short[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(int[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(int[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ - public static void parallelSort(int[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJInt.Sorter - (null, a, new int[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + public static void parallelSort(char[] a) { + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -690,16 +553,10 @@ * inclusive, to the index {@code toIndex}, exclusive. If * {@code fromIndex == toIndex}, the range to be sorted is empty. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(int[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(int[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -711,47 +568,25 @@ * * @since 1.8 */ - public static void parallelSort(int[] a, int fromIndex, int toIndex) { + public static void parallelSort(char[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJInt.Sorter - (null, a, new int[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** * Sorts the specified array into ascending numerical order. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(long[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(long[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ - public static void parallelSort(long[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJLong.Sorter - (null, a, new long[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + public static void parallelSort(short[] a) { + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -760,16 +595,10 @@ * inclusive, to the index {@code toIndex}, exclusive. If * {@code fromIndex == toIndex}, the range to be sorted is empty. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(long[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(long[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -781,17 +610,9 @@ * * @since 1.8 */ - public static void parallelSort(long[] a, int fromIndex, int toIndex) { + public static void parallelSort(short[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJLong.Sorter - (null, a, new long[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** @@ -805,31 +626,17 @@ * {@code 0.0f} and {@code Float.NaN} is considered greater than any * other value and all {@code Float.NaN} values are considered equal. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(float[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(float[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ public static void parallelSort(float[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJFloat.Sorter - (null, a, new float[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -846,16 +653,10 @@ * {@code 0.0f} and {@code Float.NaN} is considered greater than any * other value and all {@code Float.NaN} values are considered equal. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(float[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(float[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -869,15 +670,7 @@ */ public static void parallelSort(float[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJFloat.Sorter - (null, a, new float[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** @@ -891,31 +684,17 @@ * {@code 0.0d} and {@code Double.NaN} is considered greater than any * other value and all {@code Double.NaN} values are considered equal. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(double[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(double[]) Arrays.sort} method. The algorithm requires a - * working space no greater than the size of the original array. The - * {@link ForkJoinPool#commonPool() ForkJoin common pool} is used to - * execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * * @since 1.8 */ public static void parallelSort(double[] a) { - int n = a.length, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, 0, n - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJDouble.Sorter - (null, a, new double[n], 0, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, 0, a.length); } /** @@ -932,16 +711,10 @@ * {@code 0.0d} and {@code Double.NaN} is considered greater than any * other value and all {@code Double.NaN} values are considered equal. * - * @implNote The sorting algorithm is a parallel sort-merge that breaks the - * array into sub-arrays that are themselves sorted and then merged. When - * the sub-array length reaches a minimum granularity, the sub-array is - * sorted using the appropriate {@link Arrays#sort(double[]) Arrays.sort} - * method. If the length of the specified array is less than the minimum - * granularity, then it is sorted using the appropriate {@link - * Arrays#sort(double[]) Arrays.sort} method. The algorithm requires a working - * space no greater than the size of the specified range of the original - * array. The {@link ForkJoinPool#commonPool() ForkJoin common pool} is - * used to execute any parallel tasks. + * @implNote The sorting algorithm is a Dual-Pivot Quicksort by + * Vladimir Yaroslavskiy, Jon Bentley and Josh Bloch. This algorithm + * offers O(n log(n)) performance on all data sets, and is typically + * faster than traditional (one-pivot) Quicksort implementations. * * @param a the array to be sorted * @param fromIndex the index of the first element, inclusive, to be sorted @@ -955,18 +728,41 @@ */ public static void parallelSort(double[] a, int fromIndex, int toIndex) { rangeCheck(a.length, fromIndex, toIndex); - int n = toIndex - fromIndex, p, g; - if (n <= MIN_ARRAY_SORT_GRAN || - (p = ForkJoinPool.getCommonPoolParallelism()) == 1) - DualPivotQuicksort.sort(a, fromIndex, toIndex - 1, null, 0, 0); - else - new ArraysParallelSortHelpers.FJDouble.Sorter - (null, a, new double[n], fromIndex, n, 0, - ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ? - MIN_ARRAY_SORT_GRAN : g).invoke(); + DualPivotQuicksort.sort(a, RUN_IN_PARALLEL, fromIndex, toIndex); } /** + * A comparator that implements the natural ordering of a group of + * mutually comparable elements. May be used when a supplied + * comparator is null. To simplify code-sharing within underlying + * implementations, the compare method only declares type Object + * for its second argument. + * + * Arrays class implementor's note: It is an empirical matter + * whether ComparableTimSort offers any performance benefit over + * TimSort used with this comparator. If not, you are better off + * deleting or bypassing ComparableTimSort. There is currently no + * empirical case for separating them for parallel sorting, so all + * public Object parallelSort methods use the same comparator + * based implementation. + */ + static final class NaturalOrder implements Comparator { + @SuppressWarnings("unchecked") + public int compare(Object first, Object second) { + return ((Comparable)first).compareTo(second); + } + static final NaturalOrder INSTANCE = new NaturalOrder(); + } + + /** + * The minimum array length below which a parallel sorting + * algorithm will not further partition the sorting task. Using + * smaller sizes typically results in memory contention across + * tasks that makes parallel speedups unlikely. + */ + private static final int MIN_ARRAY_SORT_GRAN = 1 << 13; + + /** * Sorts the specified array of objects into ascending order, according * to the {@linkplain Comparable natural ordering} of its elements. * All elements in the array must implement the {@link Comparable}