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.
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% ...).
if
is slower than ternary? How i can determine real source of difference in performance?User contributions licensed under CC BY-SA 3.0