On Sat, 20 Sep 2025 20:36:43 GMT, Pavel Rappo <[email protected]> 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

Reply via email to