Proposal: ArrayList constructor perforrmance improvement
Scott Palmer
swpalmer at gmail.com
Tue Dec 18 19:45:03 UTC 2018
> On Dec 18, 2018, at 12:58 PM, Jason Mehrens <jason_mehrens at hotmail.com> wrote:
>
> Hi Steve,
>
>> ArrayList has a constructor which takes an arbitrary Collection as a
>> parameter. This constructor will create an iterator over the collection
>> ;and it will add each entry returned to the ArrayList.
>
>> We have found that quite a lot of the time the object passed as a
>> parameter is in fact an instance of ArrayList.
>
>> In the case of an ArrayList it is possible to significantly increase the
>> performance of the method since there is no need for an iterator - the
>> backing array can be directly copied.
>
> Maybe I'm looking at a different version of the ArrayList source code but it seems that the ArrayList constructor calls c.toArray(). If the given Collection is an ArrayList then that will call the overridden ArrayList.toArray which directly copies the backing array once and doesn't create an iterator. I would assume that most collections provide an optimized toArray().
>
> Jason
That makes sense, but the benchmarks show a notable improvement. It is worth taking a closer look to see what is going on to account for that.
toArray uses:
Arrays.copyOf(elementData, size);
which *should* be faster than:
elementData = new Object[((ArrayList)c).elementData.length];
System.arraycopy(((ArrayList)c).elementData, 0, elementData, 0, ((ArrayList)c).elementData.length);
I say should be faster, because, unlike ‘new’, internally it think it is an intrinsic that is able to get away with not zeroing the destination array prior to copying. Otherwise it is basically the same implementation, with a test to choose between new or Array.newInstance for creating the array. I wouldn’t think that test could account for the performance difference, but that’s why it needs a closer look IMO.
Scott
More information about the core-libs-dev
mailing list