今天无意中发现Arrays中有一个排序方法叫:parallelSort.
部分源码:
/**
* 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}
* interface. Furthermore, all elements in the array must be
* mutually comparable (that is, {@code e1.compareTo(e2)} must
* not throw a {@code ClassCastException} for any elements {@code e1}
* and {@code e2} in the array).
*
* This sort is guaranteed to be stable: equal elements will
* not be reordered as a result of the sort.
*
* @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(Object[]) 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(Object[]) 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.
*
* @param the class of the objects to be sorted
* @param a the array to be sorted
*
* @throws ClassCastException if the array contains elements that are not
* mutually comparable (for example, strings and integers)
* @throws IllegalArgumentException (optional) if the natural
* ordering of the array elements is found to violate the
* {@link Comparable} contract
*
* @since 1.8
*/
@SuppressWarnings("unchecked")
public static > void parallelSort(T[] a) {
int n = a.length, p, g;
if (n <= MIN_ARRAY_SORT_GRAN ||
(p = ForkJoinPool.getCommonPoolParallelism()) == 1)
TimSort.sort(a, 0, n, NaturalOrder.INSTANCE, null, 0, 0);
else
new ArraysParallelSortHelpers.FJObject.Sorter
(null, a,
(T[])Array.newInstance(a.getClass().getComponentType(), n),
0, n, 0, ((g = n / (p << 2)) <= MIN_ARRAY_SORT_GRAN) ?
MIN_ARRAY_SORT_GRAN : g, NaturalOrder.INSTANCE).invoke();
}
底层使用的是TimSort,排序结果默认是升序,并且它是一个稳定的排序方式.
好奇它的效率如何,于是乎我做了一个效率测试,让该parallelSort与Arrays.sort对比,看看谁比较快.
测试思路:
1.以整型数组来存储随机数据,数组容量逐渐递增.
2.不同容量的数组都要经过相同的n轮测试,每轮测试前都需要shuttle一次
测试的代码:
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import org.junit.Test;
public class MyTest {
//
final int UPPER_LIMIT = 0xffffff;
final int ROUNDS = 10;
final int INCREMENT = 5;
final int INIT_SIZE = 1000;
@Test
public void test() {
// 测试数组大小从INIT_SIZE开始,每次增加INCREMENT倍,直到超过UPPER_LIMIT.
for (int capacity = INIT_SIZE; capacity <= UPPER_LIMIT; capacity *= INCREMENT) {
ArrayList list = new ArrayList(capacity);
for (int i = 0; i < capacity; i++) {
list.add((int) (Math.random() * capacity));
}
// avgTimeOfParallelSort:parallelSort经过ROUNDS次排序所耗费的平均时间
double avgTimeOfParallelSort = 0;
// avgTimeOfSort:sort经过ROUNDS次排序所耗费的平均时间
double avgTimeOfSort = 0;
for (int i = 1; i <= ROUNDS; i++) {
// 每次排序都先打乱顺序
Collections.shuffle(list);
Integer[] arr1 = list.toArray(new Integer[capacity]);
Integer[] arr2 = arr1.clone();
avgTimeOfParallelSort += counter(arr1, true);
avgTimeOfSort += counter(arr2, false);
}
output(capacity, avgTimeOfParallelSort / ROUNDS, avgTimeOfSort
/ ROUNDS);
}
}
/**
* 用于计算排序花费的时间
*
* @param arr
* 要排序的数组
* @param useParallelSort
* true:使用parallelSort;false:使用sort
* @return 返回花费的时间
*/
private double counter(Integer[] arr, boolean useParallelSort) {
long begin, end;
begin = System.nanoTime();
if (useParallelSort) {
Arrays.parallelSort(arr);
} else {
Arrays.sort(arr);
}
end = System.nanoTime();
return BigDecimal.valueOf(end - begin, 9).doubleValue();
}
/**
*
* @param capacity
* 当前数组容量
* @param avgTimeOfParallelSort
* parallelSort花费的平均时间
* @param avgTimeOfSort
* sort花费的平均时间
*/
private void output(int capacity, double avgTimeOfParallelSort,
double avgTimeOfSort) {
System.out
.println("==================================================");
System.out.println("Capacity:" + capacity);
System.out.println("ParallelSort:" + avgTimeOfParallelSort);
System.out.println("Sort:" + avgTimeOfSort);
System.out.println("Winner is:"
+ (avgTimeOfParallelSort < avgTimeOfSort ? "ParallelSort"
: "Sort"));
System.out
.println("==================================================");
}
}
配置:
CPU:intel 3560M 2.4GHz
内存:8G 1600MHz
硬盘:SSD
==================================================
Capacity:1000
ParallelSort:0.0019540382999999996
Sort:0.0019829046
Winner is:ParallelSort
==================================================
==================================================
Capacity:5000
ParallelSort:0.0018625225000000003
Sort:0.0017298242
Winner is:Sort
==================================================
==================================================
Capacity:25000
ParallelSort:0.017663749599999997
Sort:0.011017932
Winner is:Sort
==================================================
==================================================
Capacity:125000
ParallelSort:0.067364954
Sort:0.0859114912
Winner is:ParallelSort
==================================================
==================================================
Capacity:625000
ParallelSort:0.2783609476
Sort:0.2758523392
Winner is:Sort
==================================================
==================================================
Capacity:3125000
ParallelSort:1.8996299160999999
Sort:1.8729492282
Winner is:Sort
==================================================
==================================================
Capacity:15625000
ParallelSort:13.23080913
Sort:12.293401009700002
Winner is:Sort
==================================================
结论:
好像效率差不多啊................是不是数据量不够大呢?还是我的电脑配置问题?