Java HashSet常量时间性能不能很好地扩展

时间:2017-09-13 15:26:17

标签: java performance hashset

在处理性能敏感代码时,我发现HashSet应该为其add,remove,contains和size方法提供恒定的时间性能,只要哈希函数返回集合中元素的唯一哈希值(HashSet Javadoc )。

执行以下代码时,我发现add方法的这种常量时间性能不成立。与使用numberOfELements = 10.000.000执行它的运行时相比,下面的代码应该大约加倍。但它需要大约3-4倍的时间。

HashSet<Integer> myHashSet;
int numberOfElements;

//Warm-up code
numberOfElements = 10000000; //10 Mio Elements
myHashSet = new HashSet(540000000); //Create HashSet with large enough initial capacity to avoid resize operations
for (int i = 0; i < numberOfElements; i++){
   myHashSet.add(i); //Add random element
}

//First benchmark
numberOfElements = 5000000; //5 Mio Elements
myHashSet.clear(); //Clear HashSet
long startTime = System.nanoTime(); //Save start time
for (int i = 0; i < numberOfElements; i++){
   myHashSet.add(i); //Add elements
}
System.out.print("Set filled with " + myJournalPoC.SFA_Journal.size() + " records in ");
System.out.println((System.nanoTime() - startTime)/1000000000 + "s");

// Second benchmark
numberOfElements = 10000000; //10 Mio Elements
myHashSet.clear(); //Clear HashSet
long startTime = System.nanoTime(); //Save start time
for (int i = 0; i < numberOfElements; i++){
   myHashSet.add(i); //Add elements
}
System.out.print("Set filled with " + myJournalPoC.SFA_Journal.size() + " records in ");
System.out.println((System.nanoTime() - startTime)/1000000000 + "s");

// Third benchmark
numberOfElements = 20000000; //20 Mio Elements
myHashSet.clear(); //Clear HashSet
long startTime = System.nanoTime(); //Save start time
for (int i = 0; i < numberOfElements; i++){
   myHashSet.add(i); //Add elements
}
System.out.print("Set filled with " + myJournalPoC.SFA_Journal.size() + " records in ");
System.out.println((System.nanoTime() - startTime)/1000000000 + "s");

// Third benchmark
numberOfElements = 40000000; //40 Mio Elements
myHashSet.clear(); //Clear HashSet
long startTime = System.nanoTime(); //Save start time
for (int i = 0; i < numberOfElements; i++){
   myHashSet.add(i); //Add elements
}
System.out.print("Set filled with " + myJournalPoC.SFA_Journal.size() + " records in ");
System.out.println((System.nanoTime() - startTime)/1000000000 + "s");

我真的很想知道这种行为的根本原因。

编辑:我在上面的例子中添加了测量性能的代码。

0 个答案:

没有答案