Difference in performance of "if" and ternary operator in Java

2

I noticed that if and ternary (condition ? a : b) have different performance, even in situations which if statement can be straightforward replaced by teranary. I performed JMH benchmarks on different JDKs but i want to focus on JDK 12.

JMH Benchmarks results: enter image description here

Source code of tested methods:

@State(Scope.Benchmark)
public class FindMaxBenchmark {
    public static int SIZE = 1_000_000;

    @Benchmark
    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public static void findMax_if(Blackhole bh, Mock mock) {
        int result = Integer.MIN_VALUE;
        int[] data = mock.tab;

        for (int i = 0; i < data.length; i++) {
            if (data[i] > result) {
                result = data[i];
            }
        }

        bh.consume(result);
    }

    @Benchmark
    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public static void findMax_ternary(Blackhole bh, Mock mock) {
        int result = Integer.MIN_VALUE;
        int[] data = mock.tab;

        for (int i = 0; i < data.length; i++) {
            result = data[i] > result ? data[i] : result;
        }

        bh.consume(result);
    }

    @Benchmark
    @CompilerControl(CompilerControl.Mode.DONT_INLINE)
    public static void findMax_intrinsicMax(Blackhole bh, Mock mock) {
        int result = Integer.MIN_VALUE;
        int[] data = mock.tab;

        for (int i = 0; i < data.length; i++) {
            result = Math.max(data[i], result);
        }

        bh.consume(result);
    }

    @State(Scope.Thread)
    public static class Mock {
        private int[] tab = new int[SIZE];

        public int[] getTab() {
            return tab;
        }

        @Setup(Level.Iteration)
        public void setup() {
            Random r = new Random();
            this.tab = r.ints(SIZE).toArray();
        }
    }
}

Perfasm output for findMax_if:

....[Hottest Region 1]..............................................................................
c2, level 4, codes.dbg.FindMaxBenchmark::findMax_if, version 494 (229 bytes)

                             ----------------------------------------------------------------------
                               0x00007fc29c66ffc0: mov    DWORD PTR [rsp-0x14000],eax
  0.01%                        0x00007fc29c66ffc7: push   rbp
                               0x00007fc29c66ffc8: sub    rsp,0x20                       ;*synchronization entry
                                                                                         ; - codes.dbg.FindMaxBenchmark::findMax_if@-1 (line 15)
                               0x00007fc29c66ffcc: mov    r10,rsi
                               0x00007fc29c66ffcf: mov    r9d,DWORD PTR [rdx+0xc]        ;*getfield tab {reexecute=0 rethrow=0 return_oop=0}
                                                                                         ; - codes.dbg.FindMaxBenchmark::findMax_if@4 (line 16)
                                                                                         ; implicit exception: dispatches to 0x00007fc29c6700f7
                               0x00007fc29c66ffd3: mov    ebp,DWORD PTR [r9+0xc]         ;*arraylength {reexecute=0 rethrow=0 return_oop=0}
                                                                                         ; - codes.dbg.FindMaxBenchmark::findMax_if@14 (line 18)
                                                                                         ; implicit exception: dispatches to 0x00007fc29c670106
                               0x00007fc29c66ffd7: mov    r11d,0x80000000
                               0x00007fc29c66ffdd: test   ebp,ebp
         ╭                     0x00007fc29c66ffdf: jbe    0x00007fc29c6700bd             ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0}
         │                                                                               ; - codes.dbg.FindMaxBenchmark::findMax_if@15 (line 18)
  0.00%  │                     0x00007fc29c66ffe5: mov    r8d,ebp
         │                     0x00007fc29c66ffe8: dec    r8d
         │                     0x00007fc29c66ffeb: cmp    r8d,ebp
         │╭                    0x00007fc29c66ffee: jae    0x00007fc29c6700c4
         ││                    0x00007fc29c66fff4: mov    edx,DWORD PTR [r9+0x10]        ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││                                                                              ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  0.00%  ││                    0x00007fc29c66fff8: cmp    edx,0x80000000
         ││╭                   0x00007fc29c66fffe: jg     0x00007fc29c670005             ;*if_icmple {reexecute=0 rethrow=0 return_oop=0}
         │││                                                                             ; - codes.dbg.FindMaxBenchmark::findMax_if@23 (line 19)
         │││                   0x00007fc29c670000: mov    edx,0x80000000                 ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         │││                                                                             ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
         ││↘                   0x00007fc29c670005: mov    ebx,ebp
  0.02%  ││                    0x00007fc29c670007: add    ebx,0xfffffffd
         ││                    0x00007fc29c67000a: cmp    r8d,ebx
         ││                    0x00007fc29c67000d: cmovl  ebx,r11d
         ││                    0x00007fc29c670011: mov    r8d,0x1
         ││                    0x00007fc29c670017: cmp    ebx,0x1
         ││ ╭                  0x00007fc29c67001a: jle    0x00007fc29c670080
         ││ │                  0x00007fc29c67001c: mov    rdi,r9                         ;*goto {reexecute=0 rethrow=0 return_oop=0}
         ││ │                                                                            ; - codes.dbg.FindMaxBenchmark::findMax_if@34 (line 18)
         ││ │╭                 0x00007fc29c67001f: jmp    0x00007fc29c670039
  0.00%  ││ ││    ↗            0x00007fc29c670021: mov    edx,ecx
  0.00%  ││ ││    │            0x00007fc29c670023: nop    DWORD PTR [rax+0x0]
         ││ ││    │            0x00007fc29c67002a: nop    WORD PTR [rax+rax*1+0x0]
  1.05%  ││ ││    │↗           0x00007fc29c670030: add    r8d,0x4                        ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         ││ ││    ││                                                                     ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
 12.81%  ││ ││    ││           0x00007fc29c670034: cmp    r8d,ebx
  0.08%  ││ ││╭   ││           0x00007fc29c670037: jge    0x00007fc29c670071             ;*aload_3 {reexecute=0 rethrow=0 return_oop=0}
         ││ │││   ││                                                                     ; - codes.dbg.FindMaxBenchmark::findMax_if@18 (line 19)
  9.77%  ││ │↘│   ││   ↗       0x00007fc29c670039: mov    r11d,DWORD PTR [r9+r8*4+0x10]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││ │ │   ││   │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  0.08%  ││ │ │   ││   │       0x00007fc29c67003e: cmp    r11d,edx
 10.00%  ││ │ │╭  ││   │       0x00007fc29c670041: jg     0x00007fc29c670062             ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         ││ │ ││  ││   │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
  0.09%  ││ │ ││  ││↗  │       0x00007fc29c670043: mov    r11d,DWORD PTR [r9+r8*4+0x14]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││ │ ││  │││  │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  9.78%  ││ │ ││  │││  │       0x00007fc29c670048: cmp    r11d,edx
  0.08%  ││ │ ││╭ │││  │       0x00007fc29c67004b: jg     0x00007fc29c670067             ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         ││ │ │││ │││  │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
  9.96%  ││ │ │││ │││↗ │       0x00007fc29c67004d: mov    r11d,DWORD PTR [r9+r8*4+0x18]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││ │ │││ ││││ │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  0.25%  ││ │ │││ ││││ │       0x00007fc29c670052: cmp    r11d,edx
 23.37%  ││ │ │││╭││││ │       0x00007fc29c670055: jg     0x00007fc29c67006c             ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         ││ │ ││││││││ │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
  0.11%  ││ │ ││││││││↗│       0x00007fc29c670057: mov    ecx,DWORD PTR [r9+r8*4+0x1c]   ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││ │ ││││││││││                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  9.87%  ││ │ ││││││││││       0x00007fc29c67005c: cmp    ecx,edx
  0.14%  ││ │ ││││╰│││││       0x00007fc29c67005e: jg     0x00007fc29c670021             ;*if_icmple {reexecute=0 rethrow=0 return_oop=0}
         ││ │ ││││ │││││                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@23 (line 19)
  9.79%  ││ │ ││││ ╰││││       0x00007fc29c670060: jmp    0x00007fc29c670030
         ││ │ │↘││  ││││       0x00007fc29c670062: mov    edx,r11d
  0.00%  ││ │ │ ││  ╰│││       0x00007fc29c670065: jmp    0x00007fc29c670043
  0.00%  ││ │ │ ↘│   │││       0x00007fc29c670067: mov    edx,r11d
  0.00%  ││ │ │  │   ╰││       0x00007fc29c67006a: jmp    0x00007fc29c67004d
         ││ │ │  ↘    ││       0x00007fc29c67006c: mov    edx,r11d
  0.00%  ││ │ │       ╰│       0x00007fc29c67006f: jmp    0x00007fc29c670057
         ││ │ ↘        │       0x00007fc29c670071: mov    r11,QWORD PTR [r15+0x108]      ; ImmutableOopMap{r10=Oop r9=NarrowOop rdi=Oop }
         ││ │          │                                                                 ;*goto {reexecute=1 rethrow=0 return_oop=0}
         ││ │          │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@34 (line 18)
  0.00%  ││ │          │       0x00007fc29c670078: test   DWORD PTR [r11],eax            ;*goto {reexecute=0 rethrow=0 return_oop=0}
         ││ │          │                                                                 ; - codes.dbg.FindMaxBenchmark::findMax_if@34 (line 18)
         ││ │          │                                                                 ;   {poll}
         ││ │          │       0x00007fc29c67007b: cmp    r8d,ebx
         ││ │          ╰       0x00007fc29c67007e: jl     0x00007fc29c670039
         ││ ↘                  0x00007fc29c670080: cmp    r8d,ebp
  0.00%  ││             ╭      0x00007fc29c670083: jge    0x00007fc29c67009a
         ││             │      0x00007fc29c670085: data16 xchg ax,ax                     ;*aload_3 {reexecute=0 rethrow=0 return_oop=0}
         ││             │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_if@18 (line 19)
         ││             │ ↗    0x00007fc29c670088: mov    r11d,DWORD PTR [r9+r8*4+0x10]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         ││             │ │                                                              ; - codes.dbg.FindMaxBenchmark::findMax_if@21 (line 19)
  0.02%  ││             │ │    0x00007fc29c67008d: cmp    r11d,edx
         ││             │╭│    0x00007fc29c670090: jg     0x00007fc29c6700b8
         ││             │││↗   0x00007fc29c670092: inc    r8d                            ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         ││             ││││                                                             ; - codes.dbg.FindMaxBenchmark::findMax_if@31 (line 18)
         ││             ││││   0x00007fc29c670095: cmp    r8d,ebp
         ││             ││╰│   0x00007fc29c670098: jl     0x00007fc29c670088             ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0}
         ││             ││ │                                                             ; - codes.dbg.FindMaxBenchmark::findMax_if@15 (line 18)
         ││             ↘│ │↗  0x00007fc29c67009a: test   r10,r10
  0.00%  ││              │ ││  0x00007fc29c67009d: je     0x00007fc29c6700da
         ││              │ ││  0x00007fc29c67009f: mov    rsi,r10
         ││              │ ││  0x00007fc29c6700a2: nop
         ││              │ ││  0x00007fc29c6700a3: call   0x00007fc29c670120             ; ImmutableOopMap{}
         ││              │ ││                                                            ;*invokevirtual consume {reexecute=0 rethrow=0 return_oop=0}
         ││              │ ││                                                            ; - codes.dbg.FindMaxBenchmark::findMax_if@39 (line 24)
         ││              │ ││                                                            ;   {optimized virtual_call}
         ││              │ ││  0x00007fc29c6700a8: add    rsp,0x20
  0.01%  ││              │ ││  0x00007fc29c6700ac: pop    rbp
         ││              │ ││  0x00007fc29c6700ad: mov    r10,QWORD PTR [r15+0x108]
         ││              │ ││  0x00007fc29c6700b4: test   DWORD PTR [r10],eax            ;   {poll_return}
         ││              │ ││  0x00007fc29c6700b7: ret
         ││              ↘ ││  0x00007fc29c6700b8: mov    edx,r11d
         ││                ╰│  0x00007fc29c6700bb: jmp    0x00007fc29c670092
         ↘│                 │  0x00007fc29c6700bd: mov    edx,0x80000000
          │                 ╰  0x00007fc29c6700c2: jmp    0x00007fc29c67009a
          ↘                    0x00007fc29c6700c4: mov    esi,0xffffff7e
                               0x00007fc29c6700c9: mov    QWORD PTR [rsp],r10
                               0x00007fc29c6700cd: mov    DWORD PTR [rsp+0x8],r9d
....................................................................................................

Perfasm output for findMax_ternary:

....[Hottest Region 1]..............................................................................
c2, level 4, codes.dbg.FindMaxBenchmark::findMax_ternary, version 480 (229 bytes)

                           ----------------------------------------------------------------------
                             0x00007f5bec66dd40: mov    DWORD PTR [rsp-0x14000],eax
  0.01%                      0x00007f5bec66dd47: push   rbp
                             0x00007f5bec66dd48: sub    rsp,0x20                       ;*synchronization entry
                                                                                       ; - codes.dbg.FindMaxBenchmark::findMax_ternary@-1 (line 30)
                             0x00007f5bec66dd4c: mov    r10,rsi
                             0x00007f5bec66dd4f: mov    r9d,DWORD PTR [rdx+0xc]        ;*getfield tab {reexecute=0 rethrow=0 return_oop=0}
                                                                                       ; - codes.dbg.FindMaxBenchmark::findMax_ternary@4 (line 31)
                                                                                       ; implicit exception: dispatches to 0x00007f5bec66de76
                             0x00007f5bec66dd53: mov    ebp,DWORD PTR [r9+0xc]         ;*arraylength {reexecute=0 rethrow=0 return_oop=0}
                                                                                       ; - codes.dbg.FindMaxBenchmark::findMax_ternary@14 (line 33)
                                                                                       ; implicit exception: dispatches to 0x00007f5bec66de82
                             0x00007f5bec66dd57: mov    r11d,0x80000000
                             0x00007f5bec66dd5d: test   ebp,ebp
  0.00%                      0x00007f5bec66dd5f: jbe    0x00007f5bec66de62             ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0}
                                                                                       ; - codes.dbg.FindMaxBenchmark::findMax_ternary@15 (line 33)
                             0x00007f5bec66dd65: mov    r8d,ebp
  0.00%                      0x00007f5bec66dd68: dec    r8d
                             0x00007f5bec66dd6b: cmp    r8d,ebp
         ╭                   0x00007f5bec66dd6e: jae    0x00007f5bec66de3d
         │                   0x00007f5bec66dd74: mov    edx,DWORD PTR [r9+0x10]        ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │                                                                             ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
         │                   0x00007f5bec66dd78: cmp    edx,0x80000000
         │╭                  0x00007f5bec66dd7e: jg     0x00007f5bec66dd85             ;*if_icmple {reexecute=0 rethrow=0 return_oop=0}
         ││                                                                            ; - codes.dbg.FindMaxBenchmark::findMax_ternary@23 (line 34)
         ││                  0x00007f5bec66dd80: mov    edx,0x80000000                 ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         ││                                                                            ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
         │↘                  0x00007f5bec66dd85: mov    ebx,ebp
  0.01%  │                   0x00007f5bec66dd87: add    ebx,0xfffffffd
         │                   0x00007f5bec66dd8a: cmp    r8d,ebx
         │                   0x00007f5bec66dd8d: cmovl  ebx,r11d
         │                   0x00007f5bec66dd91: mov    r8d,0x1
         │                   0x00007f5bec66dd97: cmp    ebx,0x1
         │ ╭                 0x00007f5bec66dd9a: jle    0x00007f5bec66de00
         │ │                 0x00007f5bec66dd9c: mov    rdi,r9                         ;*goto {reexecute=0 rethrow=0 return_oop=0}
         │ │                                                                           ; - codes.dbg.FindMaxBenchmark::findMax_ternary@38 (line 33)
         │ │╭                0x00007f5bec66dd9f: jmp    0x00007f5bec66ddb9
  0.00%  │ ││     ↗          0x00007f5bec66dda1: mov    edx,ecx
  0.00%  │ ││     │          0x00007f5bec66dda3: nop    DWORD PTR [rax+0x0]
         │ ││     │          0x00007f5bec66ddaa: nop    WORD PTR [rax+rax*1+0x0]       ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         │ ││     │                                                                    ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
  8.01%  │ ││    ↗│          0x00007f5bec66ddb0: add    r8d,0x4                        ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         │ ││    ││                                                                    ; - codes.dbg.FindMaxBenchmark::findMax_ternary@35 (line 33)
 11.17%  │ ││    ││          0x00007f5bec66ddb4: cmp    r8d,ebx
 13.85%  │ ││╭   ││          0x00007f5bec66ddb7: jge    0x00007f5bec66ddf1             ;*aload_3 {reexecute=0 rethrow=0 return_oop=0}
         │ │││   ││                                                                    ; - codes.dbg.FindMaxBenchmark::findMax_ternary@18 (line 34)
  3.04%  │ │↘│   ││   ↗      0x00007f5bec66ddb9: mov    r11d,DWORD PTR [r9+r8*4+0x10]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │ │ │   ││   │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
  8.62%  │ │ │   ││   │      0x00007f5bec66ddbe: cmp    r11d,edx
  4.61%  │ │ │╭  ││   │      0x00007f5bec66ddc1: jg     0x00007f5bec66dde2             ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         │ │ ││  ││   │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
  4.84%  │ │ ││  ││↗  │      0x00007f5bec66ddc3: mov    r11d,DWORD PTR [r9+r8*4+0x14]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │ │ ││  │││  │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
  3.83%  │ │ ││  │││  │      0x00007f5bec66ddc8: cmp    r11d,edx
  9.05%  │ │ ││╭ │││  │      0x00007f5bec66ddcb: jg     0x00007f5bec66dde7             ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         │ │ │││ │││  │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
  3.70%  │ │ │││ │││↗ │      0x00007f5bec66ddcd: mov    r11d,DWORD PTR [r9+r8*4+0x18]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │ │ │││ ││││ │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
  4.85%  │ │ │││ ││││ │      0x00007f5bec66ddd2: cmp    r11d,edx
  4.62%  │ │ │││╭││││ │      0x00007f5bec66ddd5: jg     0x00007f5bec66ddec             ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         │ │ ││││││││ │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
  8.61%  │ │ ││││││││↗│      0x00007f5bec66ddd7: mov    ecx,DWORD PTR [r9+r8*4+0x1c]   ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │ │ ││││││││││                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
  6.04%  │ │ ││││││││││      0x00007f5bec66dddc: cmp    ecx,edx
  2.44%  │ │ ││││╰│││││      0x00007f5bec66ddde: jle    0x00007f5bec66ddb0             ;*if_icmple {reexecute=0 rethrow=0 return_oop=0}
         │ │ ││││ │││││                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@23 (line 34)
         │ │ ││││ ╰││││      0x00007f5bec66dde0: jmp    0x00007f5bec66dda1
  0.00%  │ │ │↘││  ││││      0x00007f5bec66dde2: mov    edx,r11d
  0.00%  │ │ │ ││  ╰│││      0x00007f5bec66dde5: jmp    0x00007f5bec66ddc3
         │ │ │ ↘│   │││      0x00007f5bec66dde7: mov    edx,r11d
  0.00%  │ │ │  │   ╰││      0x00007f5bec66ddea: jmp    0x00007f5bec66ddcd
  0.00%  │ │ │  ↘    ││      0x00007f5bec66ddec: mov    edx,r11d
  0.00%  │ │ │       ╰│      0x00007f5bec66ddef: jmp    0x00007f5bec66ddd7
         │ │ ↘        │      0x00007f5bec66ddf1: mov    r11,QWORD PTR [r15+0x108]      ; ImmutableOopMap{r10=Oop r9=NarrowOop rdi=Oop }
         │ │          │                                                                ;*goto {reexecute=1 rethrow=0 return_oop=0}
         │ │          │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@38 (line 33)
  0.00%  │ │          │      0x00007f5bec66ddf8: test   DWORD PTR [r11],eax            ;*goto {reexecute=0 rethrow=0 return_oop=0}
         │ │          │                                                                ; - codes.dbg.FindMaxBenchmark::findMax_ternary@38 (line 33)
         │ │          │                                                                ;   {poll}
         │ │          │      0x00007f5bec66ddfb: cmp    r8d,ebx
         │ │          ╰      0x00007f5bec66ddfe: jl     0x00007f5bec66ddb9
         │ ↘                 0x00007f5bec66de00: cmp    r8d,ebp
  0.00%  │             ╭     0x00007f5bec66de03: jge    0x00007f5bec66de1a
         │             │     0x00007f5bec66de05: data16 xchg ax,ax                     ;*aload_3 {reexecute=0 rethrow=0 return_oop=0}
         │             │                                                               ; - codes.dbg.FindMaxBenchmark::findMax_ternary@18 (line 34)
         │             │ ↗   0x00007f5bec66de08: mov    r11d,DWORD PTR [r9+r8*4+0x10]  ;*iaload {reexecute=0 rethrow=0 return_oop=0}
         │             │ │                                                             ; - codes.dbg.FindMaxBenchmark::findMax_ternary@21 (line 34)
  0.02%  │             │ │   0x00007f5bec66de0d: cmp    r11d,edx
  0.00%  │             │╭│   0x00007f5bec66de10: jg     0x00007f5bec66de38             ;*istore_2 {reexecute=0 rethrow=0 return_oop=0}
         │             │││                                                             ; - codes.dbg.FindMaxBenchmark::findMax_ternary@34 (line 34)
  0.00%  │             │││↗  0x00007f5bec66de12: inc    r8d                            ;*iinc {reexecute=0 rethrow=0 return_oop=0}
         │             ││││                                                            ; - codes.dbg.FindMaxBenchmark::findMax_ternary@35 (line 33)
         │             ││││  0x00007f5bec66de15: cmp    r8d,ebp
         │             ││╰│  0x00007f5bec66de18: jl     0x00007f5bec66de08             ;*if_icmpge {reexecute=0 rethrow=0 return_oop=0}
         │             ││ │                                                            ; - codes.dbg.FindMaxBenchmark::findMax_ternary@15 (line 33)
         │             ↘│ │  0x00007f5bec66de1a: test   r10,r10
  0.00%  │              │ │  0x00007f5bec66de1d: je     0x00007f5bec66de52
         │              │ │  0x00007f5bec66de1f: mov    rsi,r10
         │              │ │  0x00007f5bec66de22: nop
         │              │ │  0x00007f5bec66de23: call   0x00007f5bec66dea0             ; ImmutableOopMap{}
         │              │ │                                                            ;*invokevirtual consume {reexecute=0 rethrow=0 return_oop=0}
         │              │ │                                                            ; - codes.dbg.FindMaxBenchmark::findMax_ternary@43 (line 37)
         │              │ │                                                            ;   {optimized virtual_call}
  0.00%  │              │ │  0x00007f5bec66de28: add    rsp,0x20
  0.01%  │              │ │  0x00007f5bec66de2c: pop    rbp
         │              │ │  0x00007f5bec66de2d: mov    r10,QWORD PTR [r15+0x108]
         │              │ │  0x00007f5bec66de34: test   DWORD PTR [r10],eax            ;   {poll_return}
         │              │ │  0x00007f5bec66de37: ret
         │              ↘ │  0x00007f5bec66de38: mov    edx,r11d
         │                ╰  0x00007f5bec66de3b: jmp    0x00007f5bec66de12
         ↘                   0x00007f5bec66de3d: mov    esi,0xffffff7e
                             0x00007f5bec66de42: mov    QWORD PTR [rsp],r10
                             0x00007f5bec66de46: mov    DWORD PTR [rsp+0x8],r9d
                             0x00007f5bec66de4b: call   0x00007f5be4ba3d00             ; ImmutableOopMap{[0]=Oop [8]=NarrowOop }
                                                                                       ;*if_icmpge {reexecute=1 rethrow=0 return_oop=0}
....................................................................................................

Full JMH + perfasm output of JDK 12 available HERE.

Observations

I see that for loops of both methods are unrolled 4 times. The only difference in disassembled code (which i can see) is:

findMax_if:

0x00007fc29c67005e: jg     0x00007fc29c670021

findMax_ternary:

0x00007f5bec66ddde: jle    0x00007f5bec66ddb0

Additionally, percentages (first, left collumn on perfasm output, i assume that these percentages indicates time spent on certain instruction) have different "distribution". In the case of findMax_if, percentage values are like steps (0%-10%-0%-10% ...), but in the case of findMax_ternary they are more homogeneously distributed (14%-3%-8%-4% ...).

  1. Why if is slower than ternary? How i can determine real source of difference in performance?
  2. How i can check is that caused by CPU branch misprediction in conditional jump (jg / jle)?

Source code on GitHub

java
performance
jvm
asked on Stack Overflow Sep 6, 2020 by Jakub Biały • edited Sep 6, 2020 by Jorn Vernee

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0