On 04/24/2018 12:41 PM, Peter Levart wrote:
public class Code {l

    static class m$switch$1 {
        static final int[] caseindex = new int[X.values().length];
        static {
            caseindex[X.A.ordinal()] = 1;
            caseindex[X.B.ordinal()] = 2;
            caseindex[X.C.ordinal()] = 3;
        }
    }

    public void m(X x) {
        switch (m$switch$1.caseindex[x.ordinal()]) {
            case 1: // ... branch A
                break;
            case 2: // ... branch B
                break;
            case 3: // ... branch C
                break;
            default: // ... default branch        }
    }
}


Pefrormance-wise this is similar to switch on int. So pretty optimal. Decision should only be made on the count of code clarity here.

While speaking of performance of enum switches, I have a question for a more knowledgeable person...

Should JIT be able to fold above 'x' variable/parameter into a constant (suppose m() was called in a loop with an explicitly specified constant value such as X.A), it could further expand this decision to the x.ordinal() value (if the final instance 'ordinal' field in the X enum class was marked with @Stable), it could then further expand this decision to the looked up value of the m$switch$1.caseindex[] slot if caseindex array field in sytnhetic class was marked with @Stable, therefore transforming the switch to a switch on int constant, optimizing the JITed code to directly execute branch A and eliminate all other branches from generated code.

The question is whether JIT is presently treating those fields (and array) as @Stable or not?

It seems not. Here's a benchmark:

http://cr.openjdk.java.net/~plevart/misc/SwitchBench/SwitchBench.java


See enumConstSwitch between "Original JDK 10" and "JDK 10 + @Stable Enum.ordinal field".

Interesting thing is that JDK 9 seems to be better at JITing code than JDK 10 in these tests. Why is that?

I included results for Graal JIT compiler which shows that it probably does not contain support for @Stable annotation.


The relevant part for this "minor regex cleanup" patch is the following:

SwitchBench.enumConstIf      avgt   10  2.125 ± 0.002  ns/op
SwitchBench.enumConstSwitch  avgt   10  2.501 ± 0.025 ns/op
SwitchBench.enumVarIf        avgt   10  2.593 ± 0.004 ns/op
SwitchBench.enumVarSwitch    avgt   10  2.862 ± 0.053 ns/op

which indicates that "switch" is a little slower, but with @Stable Enum.ordinal field, it is on par with "if" at least for constant folded switched on values:

SwitchBench.enumConstIf      avgt   10  2.126 ± 0.007 ns/op
SwitchBench.enumConstSwitch  avgt   10  2.159 ± 0.003 ns/op
SwitchBench.enumVarIf        avgt   10  2.593 ± 0.004 ns/op
SwitchBench.enumVarSwitch    avgt   10  2.842 ± 0.006 ns/op


Regards, Peter

Reply via email to