RFR: 8291769: Translation of switch with record patterns could be improved
forax at univ-mlv.fr
forax at univ-mlv.fr
Thu Aug 4 17:13:41 UTC 2022
----- Original Message -----
> From: "jan lahoda" <jan.lahoda at oracle.com>
> To: "Remi Forax" <forax at univ-mlv.fr>, "Jan Lahoda" <jlahoda at openjdk.org>, "Brian Goetz" <brian.goetz at oracle.com>
> Cc: "compiler-dev" <compiler-dev at openjdk.org>
> Sent: Thursday, August 4, 2022 6:35:18 PM
> Subject: Re: RFR: 8291769: Translation of switch with record patterns could be improved
> On 04. 08. 22 17:43, Remi Forax wrote:
>
>>
>> ----- Original Message -----
>>> From: "Jan Lahoda" <jlahoda at openjdk.org>
>>> To: compiler-dev at openjdk.org
>>> Sent: Thursday, August 4, 2022 5:04:52 PM
>>> Subject: RFR: 8291769: Translation of switch with record patterns could be
>>> improved
>>> This is an attempt to improve the performance and scalability of switches with
>>> record patterns.
>>>
>>> There are two main parts of this patch:
>>> 1. for cases of consecutive runs of cases with the same record pattern, these
>>> are replaced with a single case and a nested switch. E.g.:
>>>
>>> switch (obj) {
>>> case Box(String s) -> {}
>>> case Box(Integer i) -> {}
>>> case Box(Number n) -> {}
>>> ...
>>> }
>>> =>
>>> switch (obj) {
>>> case Box b ->
>>> switch (b.o()) {
>>> case String s -> {}
>>> case Integer i -> {}
>>> case Number n -> {}
>>> default -> continue-with-outer-switch;
>>> };
>>> ...
>>> }
>>>
>>>
>>> This is done by first unrolling the record patterns into simple binding patterns
>>> a guards, and then by finding cases with the common binding pattern as a label
>>> and a viable guard. Binding patterns are reused as much as possibly,
>>> eliminating specialized handling of record patterns as much as possible.
>> How it works when you have a record pattern followed by a type pattern with the
>> same type ?
>> Something like:
>>
>> switch (obj) {
>> case Box(String s) -> {}
>> case Box(Integer i) -> {}
>>
>> case Box b -> {}
>> }
>>
>> because you now have twice the same type pattern on the outer switch but the
>> first one should not NPE.
>
>
> Currently the `case Box b -> {}` is kept separate. It would be possible
> to merge (it would simply be a default in the nested switch), but it is
> an additional complexity in a fairly complex code already.
so depending on how a user write a switch, performance are different,
for example, with I a sealed type and A and B to subtype storing a field of type I
switch (i) {
case A(A a) -> {}
case A(B b) -> {}
case B(A a) -> {}
case B(B b) -> {}
}
vs
switch (i) {
case A(A a) -> {}
case B(A a) -> {}
case A(B b) -> {}
case B(B b) -> {}
}
that does not seem to be a good property for a desugaring, or i miss something ?
Rémi
More information about the compiler-dev
mailing list