3

Which of these runs faster in java? Suppose I want to use an ArrayList multiple times but with different values, so is it better to use clear() method or setting the arraylist to null??

panshul
  • 103
  • 2
  • 9

2 Answers2

3

1) In fact, what you want to compare is not

temp=null; versus temp.clear();

but

temp=new ArrayList<>(); versus temp.clear();

Or said differently : should we create a new ArrayList or recycle the old one by invoking clear()?

Look at this code that doesn't recycle the old ArrayList instance :

    for(int i=0;i<2000;i++)
    {
        temp=new ArrayList<Integer>();
        for(int j=0;j<2000;j++)
        {
            temp.add(j);
        }
        ret.add((ArrayList<Integer>)temp.clone());
        temp=null;
    }

temp=null is the last statement of the outer for statement and at the beginning of each iteration of this for, the ArrayList object previously referenced by the temp variable is discarded as a new ArrayList is created and assigned to.
So assigning it to null is so useless.

2) Your test has a bias.
Recycling the ArrayList instance gives better results as you have a use case that suits to.

An ArrayList is backed to an array.
At the first iteration of outer loop, the iterations of the inner loop make the backed array grows multiple times.
So at the next iterations of the outer loop, it takes advantage that the backed array has the targeted size.
So no growth of the backed array is required.

For example, if you change the code version where you recreate a new instance of ArrayList at each iteration to invoke the constructor public ArrayList(int initialCapacity) with 2000 as argument, it should improve the actual slowest version.

davidxxx
  • 125,838
  • 23
  • 214
  • 215
  • I have worked on it and removed the bias and got the opposite and shocking results. – panshul Sep 19 '17 at 20:55
  • Indeed. Difference is impressive. Note that in your example, clearing the `ArrayList` iterates 2 000 elements 2 000 times. It matters. So by specifying the target size of the ArrayList and by avoiding to iterate for clearing, this version may only be faster. – davidxxx Sep 19 '17 at 21:04
  • But when assigning a new array, that previous memory has also to be cleared by the garbage collector. – panshul Sep 19 '17 at 21:58
  • Not necessarily right now. In fact the GC doesn't collect right now as soon the object is not referenced any longer. It may happen but only if the heap consumption is close to its max size. As the object is not referenced any longer, we say that it is **eligible to be collected**. It may take some millisecond as some seconds. while `clear()` implementation iterates on all elements to set them to null : `for (int i = 0; i < size; i++) elementData[i] = null;` – davidxxx Sep 20 '17 at 09:12
1

So to know this, I ran this code two times using different ways to clear an array. First I used clear method

    `class Check
     {
        public static void main (String[] args) throws java.lang.Exception
        {
            ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
            ArrayList<Integer> temp=new ArrayList<Integer>(2000);
            for(int i=0;i<2000;i++)
            {

                for(int j=0;j<2000;j++)
                {
                    temp.add(j);
                }
                ret.add((ArrayList<Integer>)temp.clone());
                temp.clear();
            }
        }
    }

`

I got the following stats: Runtime:1.87s Memory: 4386816KB

On the other hand when I ran using null method using the following code.

`   class Check
    {
        public static void main (String[] args) throws java.lang.Exception
        {
            ArrayList<ArrayList<Integer>> ret=new ArrayList<ArrayList<Integer>>();
            ArrayList<Integer> temp;
            for(int i=0;i<2000;i++)
            {
                temp=new ArrayList<Integer>(2000);
                for(int j=0;j<2000;j++)
                {
                    temp.add(j);
                }
                ret.add((ArrayList<Integer>)temp.clone());

            }
        }
    }

` I got the stats as Runtime: 0.19s Memory: 4386816KB

So it is clear that "clear()" works slower than "null" method, although the memory used by both of them is same.

panshul
  • 103
  • 2
  • 9
  • `null` isn't a method, and you aren't doing anything to the array list *object*. You're just throwing away the *reference* to it slightly earlier than you would have otherwise. When you re-enter the loop and assign a new array list to the variable, you're also throwing away the old reference. – azurefrog Sep 19 '17 at 20:30
  • Also see https://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – azurefrog Sep 19 '17 at 20:32