Search code examples
javajvmjitjvm-hotspotjvm-bytecode

Will jvm evaluate a obvious return value on each execution?


I am sure almost everybody is familiar with the most downvoted question(java tagged) on SO. Copy pasting the snippet for completeness:

k = (j = (i = 0) + 2) + 1;
return i|= j|= k|= (j+= i) - - (k+++k) - - (i =+j);

Above snippet always returns 11 no matter what. So my question is: will jvm evaluate this/similar madness on each invocation?


Solution

  • I don't know if this counts as an answer, but it seems that the JVM can prove that no evaluation is needed:

    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Warmup(iterations = 20, time = 20)
    @Measurement(iterations = 20, time = 20)
    public class MostDownVoted {
    
        public static void main(String[] args) throws Exception {
            Options opt = new OptionsBuilder()
                .include(MostDownVoted.class.getSimpleName())
                .build();
    
            new Runner(opt).run();
        }
    
        @State(Scope.Benchmark)
        public static class Holder {
    
            int k;
            int i;
            int j;
    
            @Setup(Level.Iteration)
            public void setUp() {
                k = ThreadLocalRandom.current().nextInt();
                i = ThreadLocalRandom.current().nextInt();
                j = ThreadLocalRandom.current().nextInt();
            }
    
        }
    
        @Fork(1)
        @Benchmark
        public int test1(Holder h) {
            h.k = (h.j = (h.i = 0) + 2) + 1;
            return h.i |= h.j |= h.k |= (h.j += h.i) - -(h.k++ + h.k) - -(h.i = +h.j);
        }
    
        @Fork(1)
        @Benchmark
        public int test2(Holder h) {
            return 11;
        }
    
        @Benchmark
        @Fork(value = 1, jvmArgsAppend = "-XX:TieredStopAtLevel=1")
        public int test3(Holder h) {
            h.k = (h.j = (h.i = 0) + 2) + 1;
            return h.i |= h.j |= h.k |= (h.j += h.i) - -(h.k++ + h.k) - -(h.i = +h.j);
        }
    
    }
    

    The results show that once C2 compiler kicks in, the results with return 11 are on par with what you have :

    MostDownVoted.test1  avgt   20  2.816 ± 0.003  ns/op
    MostDownVoted.test2  avgt   20  2.122 ± 0.016  ns/op
    MostDownVoted.test3  avgt   20  3.979 ± 0.758  ns/op