I came across huge performance difference between adding 1st and 2nd item into a collection(tried ArrayList
and HashSet
), but I cannot explain why. Have searched but didn't find any answer.
public class Main {
public static void main(String[] args) {
// also tried HashSet
// also tried new ArrayList<>(2)
ArrayList<String> collection = new ArrayList<>();
long t1 = System.nanoTime();
collection.add("a");
long t2 = System.nanoTime();
collection.add("b");
long t3 = System.nanoTime();
System.out.println(String.valueOf(t2 - t1) + "\n"
+ String.valueOf(t3 - t2));
//typical output:
//4399
//1201
}
}
Some guess:
Environment: jdk11, win10, intellij.
This is because Of lazily initialized. when you are running this line
ArrayList<String> collection = new ArrayList<>();
it is only holding a reference to the list but the actual memory allocation does not happen for that list. But when you are adding the very first element to the collection then it is first allocating memory for the next 10 elements of the List (10 is the default size of array list) after that adding the first value. Results of the next 9 elements will take less time to insert but again for the 11th element, it will take more time than previous.
public static void main(String[] args) {
ArrayList<String> collection = new ArrayList<>();
for (int i = 0; i < 12; i++) {
long t1 = System.nanoTime();
collection.add("a");
long t2 = System.nanoTime();
System.out.println("Index : "+ (i+1) +": Time: "+ String.valueOf(t2 - t1));
}
/** Output:
* Index : 1: Time: 6800
Index : 2: Time: 800
Index : 3: Time: 500
Index : 4: Time: 700
Index : 5: Time: 600
Index : 6: Time: 500
Index : 7: Time: 600
Index : 8: Time: 600
Index : 9: Time: 500
Index : 10: Time: 500
Index : 11: Time: 2800
Index : 12: Time: 500
*/
}