Search code examples
javaperformancearraylistcollectionstiming

why adding first item into collection much slower than second?


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:

  • because collection is lazily initialzed when adding 1st item?
  • or I used the wrong way to measure performance?
  • or related to how jvm works(which is beyond my knowledge)?

Environment: jdk11, win10, intellij.


Solution

  • 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
         */
    
    }