ThreeSet和Collections.sort排序性能评估

0.前言

ThreeSet的底层实现是红黑树,它在创建set的过程中实现排序。Collections.sort是在对整个集合进行排序,按道理来说使用TreeSet插入集合元素直至建立整个TreeSet过程中实现排序在时间方面要比Collections.sort对整个集合进行排序效率要高很多,因为它在每次搜索要插入的位置时耗费的时间为log(n),n代表的是当前集合的长度,但实验表明使用Collections.sort对集合进行排序时间耗费要少些。

1.性能比较


测试机器:MacBook Pro、2.2GHz、Core i7、16G
2.测试代码

package com.google.common.base;

import com.google.common.collect.Lists;
import com.google.common.primitives.Ints;
import org.junit.Test;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.TreeSet;

/**
 * @author mnmlist@163.com
 * @date 2016/12/23
 * @time 19:31
 */
public class SortTest {
	public static final int DEFAULT_ARRAY_LENGTH = 10 * 1000 * 1000;

	private List<Integer> createList(int arrLength) {
		List<Integer> numbers = Lists.newArrayList();
		for(int i = 0; i < DEFAULT_ARRAY_LENGTH; i++) {
			numbers.add(i);
		}
		Collections.shuffle(numbers);
		return numbers;
	}
	public long testCollectionsSort(List<Integer> numbers) {
		Ticker ticker = Ticker.systemTicker();
		long startTime = ticker.read();
		Collections.sort(numbers, new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				return Ints.compare(o2, o1);
			}
		});
		//long endTime = ticker.read();
		//System.out.println("[testCollectionsSort]" + (endTime - startTime) / 1000);
		//System.out.println("[testCollectionsSort]" + numbers.toString());
		return (ticker.read() - startTime) / 1000;
	}

	public long testSortedMap(List<Integer> numbers) {
		Ticker ticker = Ticker.systemTicker();
		long startTime = ticker.read();
		TreeSet<Integer> sortedNumberSet = new TreeSet<Integer>(new Comparator<Integer>() {
			public int compare(Integer o1, Integer o2) {
				return Ints.compare(o2, o1);
			}
		});
		sortedNumberSet.addAll(numbers);
		//long endTime = ticker.read();
		//System.out.println("[testSortedMap]" + (endTime - startTime) / 1000);
		//List<Integer> newNumbers = Lists.newArrayList(sortedNumberSet);
		//System.out.println("[testSortedMap]" + newNumbers.toString());
		return (ticker.read() - startTime) / 1000;
	}

	@Test
	public void testSortMethodCompare() {
		int loopCount = 10;
		long collectionsSortTimeTotalCount = 0;
		long sortedMapTimeTotalCount = 0;
		List<Integer> numbers = createList(DEFAULT_ARRAY_LENGTH);
		for(int i = 0; i < loopCount; i ++) {
			List<Integer> tempNumbers = Lists.newArrayList(numbers);//每次循环使用同样数据
			sortedMapTimeTotalCount += testSortedMap(tempNumbers);//不会改变tempNumbers
			collectionsSortTimeTotalCount += testCollectionsSort(tempNumbers);
		}
		long collectionsSortTimeCount = collectionsSortTimeTotalCount / loopCount;
		long sortedMapTimeCount = sortedMapTimeTotalCount / loopCount;
		System.out.println("[testSortMethodCompare] loopCount = " + loopCount
				+ ",listSize = " + DEFAULT_ARRAY_LENGTH);
		System.out.println("[CollectinSort]" + collectionsSortTimeCount + "微秒");
		System.out.println("[SortedMapSort]" + sortedMapTimeCount + "微秒");
	}
}

3.性能差异分析

a.TreeSet每次搜索要插入的位置时耗费的时间为log(n),n代表的是当前集合的长度,n从1增加至排序的数据集合list的list.size(),这个相比Collections.sort直接对整个数据集合进行排序具有优势。

b.TreeSet一个明显的劣势排序的过程是插入新节点的过程,创建新节点,插入新节点应该也会耗费一定的时间。

c.TreeSet另一个明显的劣势为由于其底层实现为红黑树,所以每次插入后需要对原有的集合进行修改以使得新集合底层仍然是红黑树。

以上是TreeSet实现排序的优势和劣势,由性能比较数据可以看出,相比TreeSet实现排序的优势,其劣势更明显。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值