所以在编程讲座中,讲师给了我们一些关于一些Java Collections的性能的数据。他使用了这篇文章中给出的数据。.
然后我和我的伙伴决定亲自测试一下。但我们的测量结果与帖子中给出的结果有很大不同。我们测试了下面列出的集合的“添加”、“包含”、“删除”和“清除”。里面还放了几张地图。哈希集 树集 链接哈希集 数组列表 链表 数组双端队列 优先队列 哈希映射 树形图 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);
}
}
它给出了以下输出:
哈希集:添加:225 ns树集:添加:430 ns
链接哈希集:添加:46 ns
链表:添加:61 ns
数组列表:添加:33 ns
优先级队列:添加:45 ns
数组双端队列:添加:55 ns
哈希映射:添加:40 ns
树图:添加:166 ns
链接哈希图:添加:43 ns
哈希集:包含:235 ns
树集:包含:456 ns
链接哈希集:包含:57 ns
链接列表:包含:163147 ns
数组列表:包含:45355 ns
优先级队列:包含:35929 ns
数组双端队列:包含:53337 ns
哈希映射:包含:90 ns
树图:包含:380 ns
链接哈希图:包含:51 ns
哈希集:删除:506 ns
树集:删除:1236 ns
链接哈希集:删除:150 ns
链表:删除:54833 ns
数组列表:删除:16115 ns
优先级队列:删除:31837 ns
数组双端队列:删除:35739 ns
哈希映射:删除:110 ns
树图:删除:823 ns
链接哈希图:删除:129 ns
哈希集:清除:32998 ns
树集:清晰:322 ns
链接哈希集:清除:33273 ns
链接列表:清除:213397 ns
数组列表:清除:24334 ns
优先级队列:清除:25343 ns
数组双端队列:清除:45598 ns
哈希映射:清除:33457 ns
树图:清晰:27 ns
链接哈希图:清除:33289 ns
如您所见,与其他结果相比,TreeSet 上的“清晰”结果与讲座中给出的值(帖子中的值)完全不匹配。
我们做错了什么吗?我的意思是,我们必须如此!它是什么?请问有什么帮助吗?
我们尝试编写自己的代码,如上所示。我们看了很长时间,但什么也没弄清楚。请记住,我们是初级 Java 程序员;只学习了3周。
我们做错了什么吗?我的意思是,我们必须如此!它是什么?请问有什么帮助吗?为什么?您链接到的帖子没有代码来验证其结果。它甚至没有列出运行测试的 JVM 和架构。
TreeSet.clear 速度很快。至少,它是在 JDK21 上;我没有看过早期版本,但是,我很确定它
总是以这种方式工作:
TreeSet
没什么 - 它只是创建一个
TreeMap
并将每个调用降级到地图。该映射中的键是树集中的值;这些值是无关紧要的(
PRESENT
- 单个
new Object()
只是为了有一些“值”来映射这些键)。
ts.clear()
只需调用 TreeSet 所构建的地图的
clear()
方法。
应该是完全无视.
您应该引导您的教授解决这个问题,并确保他们不再将这些问题传播给未来的学生。你的同学/未来的学生谢谢你!