Kind reminder about JDK-8193031
Stuart Marks
stuart.marks at oracle.com
Fri Jun 14 01:33:04 UTC 2019
Hi Sergey,
There are some links to a few other discussion threads in the bug report [1].
I've added a link to this one. :-)
It's too late for JDK 13, which entered RDP1 today. However, the JDK 14 source
base is open, and we can proceed there.
In one of the previous discussions, I had suggested an alternative which is to
add a default method ("addEach") that adds to a collection all the elements of a
given array. This was probably a distraction from that discussion, and it might
have had the side effect of derailing that discussion. So, sorry about that.
Let's focus on Martin's proposal. Basically this replaces the for-loop with code
that wraps the array with Arrays.asList and then simply calls Collection.addAll.
There is also some spec cleanup.
Overall I think this is fine, but I did have a reservation. If we have
Collections.addAll(arraylist, array)
this would end up calling
arraylist.addAll(Arrays.asList(array))
The first thing ArrayList.addAll() does is
Object[] a = c.toArray();
which makes a copy of the input array. Right away, this seems like a waste.
On the other hand, I observed that doing two bulk array copies was actually
faster than making one copy using a for-loop. I don't remember what sizes I
checked. I'm a bit surprised, though, I would have thought that some sizes would
be faster and some slower. Perhaps someone should do some more benchmarks. But
that seems like an advantage of using addAll.
One thing I didn't think of previously was that using a for-loop to add elements
one-at-a-time might resize the destination ArrayList more than once, resulting
in some redundant copying, whereas a bulk copy with addAll() will resize the
destination at most once before doing the copy. That's another point in favor of
using addAll().
In summary, while this might seem like an obvious thing to do, it's not a
no-brainer, and there are some subtle tradeoffs. We might end up doing this
eventually, but it would be good to have a better handle on the tradeoffs and
potential impact.
Martin was working on this most recently. Martin, what do you think?
s'marks
On 6/13/19 4:39 AM, Сергей Цыпанов wrote:
> Hello,
>
> the issue [1] was opened almost two years ago,
> but even today Collections.addAll still looks like this:
>
> public static <T> boolean addAll(Collection<? super T> c, T... elements) {
> boolean result = false;
> for (T element : elements)
> result |= c.add(element);
> return result;
> }
>
> The most wide-spread collections in Java-world is ArrayList for which Collections.addAll is likely to be slower then Collection.addAll(Arrays.asList).
> The same is valid for ArrayDeque and especially for COWList. There's a webrev [2] for mentioned ticket. The whole story begins in [3].
>
> Could the change [2] be done for JDK 13?
>
> Regards,
> Sergey Tsypanov
>
>
> 1. https://bugs.openjdk.java.net/browse/JDK-8193031
> 2. http://cr.openjdk.java.net/~martin/webrevs/jdk/Collections-addAll
> 3. http://mail.openjdk.java.net/pipermail/core-libs-dev/2017-December/050326.html
>
More information about the core-libs-dev
mailing list