RFR: 8368178: Add specialization of SequencedCollection methods to emptyList, singletonList and nCopies
Tagir F. Valeev
tvaleev at openjdk.org
Sun Sep 21 10:47:11 UTC 2025
On Sat, 20 Sep 2025 20:36:43 GMT, Pavel Rappo <prappo at openjdk.org> wrote:
>> Please review this small change. If you have more ideas which classes may miss specializations of SequencedCollection methods, I can add them to this PR as well.
>
>> If you have more ideas which classes may miss specializations of SequencedCollection methods, I can add them to this PR as well.
>
> Have you considered something like this?
>
> diff --git a/src/java.base/share/classes/java/util/ImmutableCollections.java b/src/java.base/share/classes/java/util/ImmutableCollections.java
> index 38cc45122a2..d8c3499a958 100644
> --- a/src/java.base/share/classes/java/util/ImmutableCollections.java
> +++ b/src/java.base/share/classes/java/util/ImmutableCollections.java
> @@ -352,7 +352,7 @@ public boolean contains(Object o) {
>
> @Override
> public List<E> reversed() {
> - return ReverseOrderListView.of(this, false);
> + return size() < 2 ? this : ReverseOrderListView.of(this, false);
> }
>
> IndexOutOfBoundsException outOfBounds(int index) {
> @@ -636,6 +636,11 @@ public int lastIndexOf(Object o) {
> }
> }
>
> + @Override
> + public List<E> reversed() {
> + return size() == 1 ? this : super.reversed();
> + }
> +
> @java.io.Serial
> private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
> throw new InvalidObjectException("not serial proxy");
@pavelrappo re `ImmutableCollections`, I was thinking about them. One thing that bugs me is that `List.copyOf(immutableList)` doesn't copy, but `List.copyOf(immutableList.reversed())` produces a fresh copy. Probably this is not a very common scenario to optimize, though.
Re `List12.reversed()` with size == 2: probably it's better to create a fresh list like `new List12<>(e1, e0)`, like
@SuppressWarnings("unchecked")
@Override
public List<E> reversed() {
return e1 == EMPTY ? this : new List12<>((E) e1, e0);
}
This way, we have fewer indirections and always return the instance of `List12`, which may probably help with devirtualization sometimes. The `List12` instance size is small. With compressed OOPs it's likely the same size as `ReverseOrderListView` (two object fields, compared to object+boolean fields in `ReverseOrderListView`), and the original list could become eligible for GC. One downside of this approach is that `listOf2.reversed().reversed()` will return a fresh instance, rather than the original one. But I guess it's a rare scenario and the cost is still small. What do you think?
-------------
PR Comment: https://git.openjdk.org/jdk/pull/27406#issuecomment-3315911606
More information about the core-libs-dev
mailing list