On Thu, 17 Dec 2020 10:15:23 GMT, Сергей Цыпанов <github.com+10835776+stsypa...@openjdk.org> wrote:
>> Hello, I feel like this was previously discussed in >> https://mail.openjdk.java.net/pipermail/core-libs-dev/ but since I cannot >> find original mail I post this here. >> >> Currently `Collections.addAll()` is implemented and documented as: >> /** >> * ... >> * The behavior of this convenience method is identical to that of >> * {@code c.addAll(Arrays.asList(elements))}, but this method is likely >> * to run significantly faster under most implementations. >> */ >> @SafeVarargs >> public static <T> boolean addAll(Collection<? super T> c, T... elements) >> { >> boolean result = false; >> for (T element : elements) >> result |= c.add(element); >> return result; >> } >> >> But it practice the notation `this method is likely to run significantly >> faster under most implementations` is completely wrong. When I take this >> [benchmark](https://github.com/stsypanov/benchmarks/blob/master/benchmark-runners/src/main/java/com/luxoft/logeek/benchmark/collection/CollectionsAddAllVsAddAllBenchmark.java) >> and run it on JDK 14 I get the following results: >> (collection) (size) >> Score Error Units >> addAll ArrayList 10 >> 37.9 ± 1.9 ns/op >> addAll ArrayList 100 >> 83.8 ± 3.4 ns/op >> addAll ArrayList 1000 >> 678.2 ± 23.0 ns/op >> collectionsAddAll ArrayList 10 >> 50.9 ± 1.1 ns/op >> collectionsAddAll ArrayList 100 >> 751.4 ± 47.4 ns/op >> collectionsAddAll ArrayList 1000 >> 8839.8 ± 710.7 ns/op >> >> addAll HashSet 10 >> 128.4 ± 5.9 ns/op >> addAll HashSet 100 >> 1864.2 ± 102.4 ns/op >> addAll HashSet 1000 >> 16615.5 ± 1202.6 ns/op >> collectionsAddAll HashSet 10 >> 172.8 ± 6.0 ns/op >> collectionsAddAll HashSet 100 >> 2355.8 ± 195.4 ns/op >> collectionsAddAll HashSet 1000 >> 20364.7 ± 1164.0 ns/op >> >> addAll ArrayDeque 10 >> 54.0 ± 0.4 ns/op >> addAll ArrayDeque 100 >> 319.7 ± 2.5 ns/op >> addAll ArrayDeque 1000 >> 3176.9 ± 22.2 ns/op >> collectionsAddAll ArrayDeque 10 >> 66.5 ± 1.4 ns/op >> collectionsAddAll ArrayDeque 100 >> 808.1 ± 55.9 ns/op >> collectionsAddAll ArrayDeque 1000 >> 5639.6 ± 240.9 ns/op >> >> addAll CopyOnWriteArrayList 10 >> 18.0 ± 0.7 ns/op >> addAll CopyOnWriteArrayList 100 >> 39.4 ± 1.7 ns/op >> addAll CopyOnWriteArrayList 1000 >> 371.1 ± 17.0 ns/op >> collectionsAddAll CopyOnWriteArrayList 10 >> 251.9 ± 18.4 ns/op >> collectionsAddAll CopyOnWriteArrayList 100 >> 3405.9 ± 304.8 ns/op >> collectionsAddAll CopyOnWriteArrayList 1000 >> 247496.8 ± 23502.3 ns/op >> >> addAll ConcurrentLinkedDeque 10 >> 81.4 ± 2.8 ns/op >> addAll ConcurrentLinkedDeque 100 >> 609.1 ± 26.4 ns/op >> addAll ConcurrentLinkedDeque 1000 >> 4494.5 ± 219.3 ns/op >> collectionsAddAll ConcurrentLinkedDeque 10 >> 189.8 ± 2.5 ns/op >> collectionsAddAll ConcurrentLinkedDeque 100 >> 1660.0 ± 62.0 ns/op >> collectionsAddAll ConcurrentLinkedDeque 1000 >> 17649.2 ± 300.9 ns/op >> >> addAll:·gc.alloc.rate.norm ArrayList 10 >> 160.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ArrayList 100 >> 880.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ArrayList 1000 >> 8080.3 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayList 10 >> 80.0 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayList 100 >> 1400.2 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayList 1000 >> 15025.6 ± 0.1 B/op >> >> addAll:·gc.alloc.rate.norm HashSet 10 >> 464.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm HashSet 100 >> 5328.5 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm HashSet 1000 >> 48516.7 ± 0.1 B/op >> collectionsAddAll:·gc.alloc.rate.norm HashSet 10 >> 464.0 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm HashSet 100 >> 5328.5 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm HashSet 1000 >> 48516.6 ± 0.1 B/op >> >> addAll:·gc.alloc.rate.norm ArrayDeque 10 >> 112.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ArrayDeque 100 >> 560.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ArrayDeque 1000 >> 4160.5 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayDeque 10 >> 112.0 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayDeque 100 >> 1048.1 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ArrayDeque 1000 >> 14929.4 ± 0.0 B/op >> >> addAll:·gc.alloc.rate.norm CopyOnWriteArrayList 10 >> 88.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm CopyOnWriteArrayList 100 >> 448.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm CopyOnWriteArrayList 1000 >> 4048.1 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm CopyOnWriteArrayList 10 >> 456.0 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm CopyOnWriteArrayList 100 >> 22057.2 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm CopyOnWriteArrayList 1000 >> 2020150.3 ± 7.3 B/op >> >> addAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 10 >> 312.0 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 100 >> 2472.1 ± 0.0 B/op >> addAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 1000 >> 24073.7 ± 0.1 B/op >> collectionsAddAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 10 >> 288.0 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 100 >> 2448.3 ± 0.0 B/op >> collectionsAddAll:·gc.alloc.rate.norm ConcurrentLinkedDeque 1000 >> 24051.4 ± 0.3 B/op >> There's never a case when `Collections.addAll` is fater - on the contrary >> `c.addAll(Arrays.asList())` always wins. Pay attention especially to >> dramatic difference for array-based collection. >> >> So I propose to reimplement the method by simply delegating to >> `Arrays.asList` because the spec declares identical behaviour and to remove >> perfomance notation from JavaDoc. > > Looks like I've found the original ticket: > https://bugs.openjdk.java.net/browse/JDK-8193031 Apart from the @SuppressWarnings, this looks good to me. And i like the irony of this. ------------- PR: https://git.openjdk.java.net/jdk/pull/1764