Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write the clear() method in the list data structure?

I have read some frameworks source code recently and noticed that they written the clear() method of a list-like data structure like this. Delete the elements one by one.

while (_arr.length > 0 )
{

    remove(_arr[0]);

}       

(maybe the above look like a little confusing,but it's because the native array type in this language itself was a dynamic array) or

 for (int i = 0; i < size; i++)
  { elementData[i] = null;}
 size = 0;

But i remembered i have written some code like this. The list decorated native array type,and I have written clear() method like this.

 _arr=new Array();
 _size=0;

instantiate a new native array type directly.

and this code are written in the language that has the garbage collection. so I think all elements finally will be collected,so why there need a loop?Is a new will be fast?

like image 691
BlackCat Avatar asked Aug 22 '17 09:08

BlackCat


People also ask

What does list Clear () function do?

The clear() method removes all the elements from a list.

How do you clear a list in Python?

The clear() method removes all items from the list.

What is clear () in Java?

The Java ArrayList clear() method removes all the elements from an arraylist. The syntax of the clear() method is: arraylist.clear() Here, arraylist is an object of the ArrayList class.

What is Python clear ()?

The clear() function in Python removes all elements from a list. The function does not take any parameters and does not return anything.


3 Answers

I guess the motivation is re-using the existing backing array instead of allocating a new one. This is important especially when the backing array is very large (which in some rare cases can even mean the new array cannot be allocated before the old one is garbage collected).

Allocating a new array (and garbage collecting the old one) is probably more time consuming than iterating over the existing array and setting the references of all the elements to null.

EDIT: As mentioned in the comments, setting the references to null in an array based List is not enough. You also have to indicate that the List is empty. In java.util.ArrayList this is done by setting the size property to 0.

like image 131
Eran Avatar answered Oct 04 '22 04:10

Eran


In some contexts, it is more efficient to clear and reuse the backing array. (Obviously, you need a size field and you need to set that to zero when you clear the list!)

  • Clearing reduces the garbage generated when you empty the list.
  • If you grow the list incrementally (i.e. without a capacity hint), clearing also reduces garbage generated by reallocations.

But the flipside is that it isn't always a good idea to clear. For example;

  • If you call clear on a ArrayList, the size of the backing array remains the same size as it was when the list was full. If the list was very long, the array can be very big big. And if you never need the list to be that long again, the large array can waste a lot of space.

  • The GC has to check every cell in an ArrayList's backing array anyway, irrespective of the current value of the size field. And it needs to copy the entire array to the "to" space.

  • That also means that you need to assign null to the "cleared" cells to avoid memory leaks.

  • There can be secondary performance issues due to generational and/or locality factors if you are continually putting "new" objects into a large "old" array.

In short, if an array-backed list is likely to survive multiple GC cycles, then clearing (i.e. the procedure of clearing out and reusing the backing array) is a dubious proposition.

like image 32
Stephen C Avatar answered Oct 04 '22 02:10

Stephen C


Should probably be a comment, but it will not fit as such I assume.

There is also the fact that besides allocating an array might be too expensive and clearing the previous array would be cheaper, there is also the fact that allocating an array in the form new byte[100] or whatever has to also do the zeroing the contents, which might be expensive also.

As such in java-9 String concatenation uses the UNSAFE.allocateUninitializedArray that specifically says Allocates an array of a given type, but does not do zeroing. and of course also adds:

This method should only be used in the very rare cases where a high-performance code overwrites the destination array completely, and compilers cannot assist in zeroing elimination. In an overwhelming majority of cases, a normal Java allocation should be used instead.

And this is how the actual method looks like:

    @ForceInline
    private static byte[] newArray(int length, byte coder) {
        return (byte[]) UNSAFE.allocateUninitializedArray(byte.class, length << coder);
    }

This is just to prove that there are cases where it is in fact too expensive to create arrays and it's cheaper not to. Especially since arrays might require contiguous memory allocation - but this is not mandated by the spec.

like image 30
Eugene Avatar answered Oct 04 '22 02:10

Eugene