Java集合性能测试结果与参考数据不符,请求排查问题
Java集合性能测试结果与预期不符的问题排查
问题背景
我们在编程课程中参考了Java集合性能对比的相关资料,自行测试了多种集合及Map的add、contains、remove、clear操作,但测试结果与参考数据差异很大。测试覆盖的集合/Map包括:
- HashSet、TreeSet、LinkedHashSet
- ArrayList、LinkedList
- ArrayDeque、PriorityQueue
- HashMap、TreeMap、LinkedHashMap
我们执行了100次测试并计算平均值,测试代码如下:
import java.util.*; public class Testing { public void initializeAndRun(int testCases){ Set<Integer> hashSet = new HashSet<>(); Set<Integer> treeSet = new TreeSet<>(); Set<Integer> linkedHashSet = new LinkedHashSet<>(); List<Integer> linkedList = new LinkedList<>(); List<Integer> arrayList = new ArrayList<>(); Queue<Integer> priorityQueue = new PriorityQueue<>(); Queue<Integer> arrayDeque = new ArrayDeque<>(); Map<Integer, Integer> hashMap = new HashMap<>(); Map<Integer, Integer> treeMap = new TreeMap<>(); Map<Integer, Integer> linkedHashMap = new LinkedHashMap<>(); testSet(hashSet, "Hash Set","add", testCases); testSet(treeSet, "Tree Set","add", testCases); testSet(linkedHashSet, "Linked Hash Set", "add", testCases); testList(linkedList, "Linked List", "add", testCases); testList(arrayList, "Array List", "add", testCases); testQueue(priorityQueue, "Priority Queue", "add", testCases); testQueue(arrayDeque, "Array Deque", "add", testCases); testMap(hashMap, "Hash Map", "add", testCases); testMap(treeMap, "Tree Map", "add", testCases); testMap(linkedHashMap, "Linked Hash Map", "add", testCases); System.out.println(); testSet(hashSet, "Hash Set","contains", testCases); testSet(treeSet, "Tree Set","contains", testCases); testSet(linkedHashSet, "Linked Hash Set", "contains", testCases); testList(linkedList, "Linked List", "contains", testCases); testList(arrayList, "Array List", "contains", testCases); testQueue(priorityQueue, "Priority Queue", "contains", testCases); testQueue(arrayDeque, "Array Deque", "contains", testCases); testMap(hashMap, "Hash Map", "contains", testCases); testMap(treeMap, "Tree Map", "contains", testCases); testMap(linkedHashMap, "Linked Hash Map", "contains", testCases); System.out.println(); testSet(hashSet, "Hash Set","remove", testCases); testSet(treeSet, "Tree Set","remove", testCases); testSet(linkedHashSet, "Linked Hash Set", "remove", testCases); testList(linkedList, "Linked List", "remove", testCases); testList(arrayList, "Array List", "remove", testCases); testQueue(priorityQueue, "Priority Queue", "remove", testCases); testQueue(arrayDeque, "Array Deque", "remove", testCases); testMap(hashMap, "Hash Map", "remove", testCases); testMap(treeMap, "Tree Map", "remove", testCases); testMap(linkedHashMap, "Linked Hash Map", "remove", testCases); System.out.println(); testSet(hashSet, "Hash Set","clear", testCases); testSet(treeSet, "Tree Set","clear", testCases); testSet(linkedHashSet, "Linked Hash Set", "clear", testCases); testList(linkedList, "Linked List", "clear", testCases); testList(arrayList, "Array List", "clear", testCases); testQueue(priorityQueue, "Priority Queue", "clear", testCases); testQueue(arrayDeque, "Array Deque", "clear", testCases); testMap(hashMap, "Hash Map", "clear", testCases); testMap(treeMap, "Tree Map", "clear", testCases); testMap(linkedHashMap, "Linked Hash Map", "clear", testCases); System.out.println(); } private void loadSet(Set<Integer> input){ input.clear(); Random randInt = new Random(); for(int i = 0; i < 100000; i++){ Integer x = randInt.nextInt(100000); input.add(x); } } private void loadList(List<Integer> input){ input.clear(); Random randInt = new Random(); for(int i = 0; i < 100000; i++){ Integer x = Integer.valueOf(randInt.nextInt(100000)); input.add(x); } } private void loadQueue(Queue<Integer> input){ input.clear(); Random randInt = new Random(); for(int i = 0; i < 100000; i++){ Integer x = Integer.valueOf(randInt.nextInt(100000)); input.add(x); } } private void loadMap(Map<Integer, Integer> input){ input.clear(); Random randInt = new Random(); for(int i = 0; i < 100000; i++){ Integer x = Integer.valueOf(randInt.nextInt(100000)); input.put(x, x); } } private void testSet(Set<Integer> input, String name, String test, int testNo){ long totalTime = 0; long start = 0; long end = 0; Random rand = new Random(); for(int i = 0; i < testNo; i++){ loadSet(input); Integer x = Integer.valueOf(rand.nextInt(10000)); if(test.equals("add")) { start = System.nanoTime(); input.add(x); end = System.nanoTime(); input.remove(x); }else if(test.equals("contains")){ start = System.nanoTime(); input.contains(x); end = System.nanoTime(); }else if(test.equals("remove")){ Object[] array = input.toArray(); int index = rand.nextInt(array.length); int element = (int) array[index]; start = System.nanoTime(); input.remove(element); end = System.nanoTime(); input.add(element); }else if(test.equals("clear")){ start = System.nanoTime(); input.clear(); end = System.nanoTime(); } totalTime += end - start; } long averageTime = totalTime/testNo; printResult(name, test, averageTime); } private void testList(List<Integer> input, String name, String test, int testNo){ long totalTime = 0; long start = 0; long end = 0; Random rand = new Random(); for(int i = 0; i < testNo; i++){ loadList(input); Integer x = Integer.valueOf(rand.nextInt(10000)); if(test.equals("add")) { start = System.nanoTime(); input.add(x); end = System.nanoTime(); input.remove(x); }else if(test.equals("contains")){ start = System.nanoTime(); input.contains(x); end = System.nanoTime(); }else if(test.equals("remove")){ Object[] array = input.toArray(); int index = rand.nextInt(array.length); int element = (int) array[index]; start = System.nanoTime(); input.remove(element); end = System.nanoTime(); input.add(element); }else if(test.equals("clear")){ start = System.nanoTime(); input.clear(); end = System.nanoTime(); } totalTime += end - start; } long averageTime = totalTime/testNo; printResult(name, test, averageTime); } private void testQueue(Queue<Integer> input, String name, String test, int testNo){ long totalTime = 0; long start = 0; long end = 0; Random rand = new Random(); for(int i = 0; i < testNo; i++){ loadQueue(input); Integer x = Integer.valueOf(rand.nextInt(10000)); if(test.equals("add")) { start = System.nanoTime(); input.add(x); end = System.nanoTime(); input.remove(x); }else if(test.equals("contains")){ start = System.nanoTime(); input.contains(x); end = System.nanoTime(); }else if(test.equals("remove")){ Object[] array = input.toArray(); int index = rand.nextInt(array.length); int element = (int) array[index]; start = System.nanoTime(); input.remove(element); end = System.nanoTime(); input.add(element); }else if(test.equals("clear")){ start = System.nanoTime(); input.clear(); end = System.nanoTime(); } totalTime += end - start; } long averageTime = totalTime/testNo; printResult(name, test, averageTime); } private void testMap(Map<Integer, Integer> input, String name, String test, int testNo){ long totalTime = 0; long start = 0; long end = 0; Random rand = new Random(); for(int i = 0; i < testNo; i++){ loadMap(input); Integer x = Integer.valueOf(rand.nextInt(10000)); if(test.equals("add")) { start = System.nanoTime(); input.put(x, x); end = System.nanoTime(); input.remove(x, x); }else if(test.equals("contains")){ start = System.nanoTime(); input.containsKey(x); end = System.nanoTime(); }else if(test.equals("remove")){ Set<Integer> keysSet = input.keySet(); Integer[] array = new Integer[keysSet.size()]; keysSet.toArray(array); int index = rand.nextInt(array.length); int element = (int) array[index]; start = System.nanoTime(); input.remove(element); end = System.nanoTime(); input.put(element, element); }else if(test.equals("clear")){ start = System.nanoTime(); input.clear(); end = System.nanoTime(); } totalTime += end - start; } long averageTime = totalTime/testNo; printResult(name, test, averageTime); } private void printResult(String name, String test, long averageTime){ System.out.printf("%s: %s: %d ns%n", name,test, averageTime); } public static void main(String[] args){ Testing test = new Testing(); int testCases = 100; test.initializeAndRun(testCases); } }
测试输出结果
Add操作(单位:纳秒)
Hash Set: add: 225 ns Tree Set: add: 430 ns Linked Hash Set: add: 46 ns Linked List: add: 61 ns Array List: add: 33 ns Priority Queue: add: 45 ns Array Deque: add: 55 ns Hash Map: add: 40 ns Tree Map: add: 166 ns Linked Hash Map: add: 43 ns
Contains操作(单位:纳秒)
Hash Set: contains: 235 ns Tree Set: contains: 456 ns Linked Hash Set: contains: 57 ns Linked List: contains: 163147 ns Array List: contains: 45355 ns Priority Queue: contains: 35929 ns Array Deque: contains: 53337 ns Hash Map: contains: 90 ns Tree Map: contains: 380 ns Linked Hash Map: contains: 51 ns
Remove操作(单位:纳秒)
Hash Set: remove: 506 ns Tree Set: remove: 1236 ns Linked Hash Set: remove: 150 ns Linked List: remove: 54833 ns Array List: remove: 16115 ns Priority Queue: remove: 31837 ns Array Deque: remove: 35739 ns Hash Map: remove: 110 ns Tree Map: remove: 823 ns Linked Hash Map: remove: 129 ns
Clear操作(单位:纳秒)
Hash Set: clear: 32998 ns Tree Set: clear: 322 ns Linked Hash Set: clear: 33273 ns Linked List: clear: 213397 ns Array List: clear: 24334 ns Priority Queue: clear: 25343 ns Array Deque: clear: 45598 ns Hash Map: clear: 33457 ns Tree Map: clear: 27 ns Linked Hash Map: clear: 33289 ns
可以看到,TreeSet的clear操作等结果与课程给出的数据完全不符。我们仅学习Java3周,希望能找到问题所在。
内容的提问来源于stack exchange,提问作者Shakthi Weerawansa
相关产品推荐
相关产品推荐

