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
     * <i>mutually comparable</i> (that is, {@code e1.compareTo(e2)} must
     * not throw a {@code ClassCastException} for any elements {@code e1}
     * and {@code e2} in the array).
     *
     * <p>This sort is guaranteed to be <i>stable</i>:  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 <T> 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
     *         <i>mutually comparable</i> (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 <T extends Comparable<? super T>> 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<T>
                (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<Integer> list = new ArrayList<Integer>(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
==================================================

结论:

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值