jdk8 parallelSort并行排序

今天无意中发现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
==================================================

结论:

好像效率差不多啊................是不是数据量不够大呢?还是我的电脑配置问题?

你可能感兴趣的:(--14.2.校招准备)