Slide 1

Slide 1 text

Performance by Dmitry Vyazelenko @ Voxxed Days Zurich 2018

Slide 2

Slide 2 text

About me • Senior Software Engineer @ Canoo Engineering AG, Switzerland • Disorganizer at JCrete (jcrete.org) and Jalba (jalba.scot) Unconferences • Contacts: vyazelenko.com, @DVyazelenko

Slide 3

Slide 3 text

Agenda ● Java’s new release cadence ● Modular JDK: startup and footprint ● JEP 243: Java-Level JVM Compiler Interface ● JEP 248: Make G1 the Default Garbage Collector ● JEP 254: Compact Strings ● JEP 280: Indify String Concatenation ● JEP 269: Convenience Factory Methods for Collections ● JEP 259: Stack-Walking API ● New APIs

Slide 4

Slide 4 text

Java’s new release cadence

Slide 5

Slide 5 text

See also [4] Java: Stable, Secure and Free. Choose Two out of Three

Slide 6

Slide 6 text

Modular JDK: startup and footprint

Slide 7

Slide 7 text

Modules JEP 200: The Modular JDK JEP 201: Modular Source Code JEP 220: Modular Run-Time Images JEP 261: Module System JEP 275: Modular Java Application Packaging JEP 282: jlink: The Java Linker JEP 295: Ahead-of-Time Compilation

Slide 8

Slide 8 text

Footprint Download size, MB Installed size, MB jdk1.8.0_162 166 395 jre1.8.0_162 60 206 jdk-9.0.4 305 577 jre-9.0.4 60 237

Slide 9

Slide 9 text

package com.vyazelenko.hello; public class Hello { public static void main(String[] args) { System.out.println("Hello, world!"); } }

Slide 10

Slide 10 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91

Slide 11

Slide 11 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91 $JDK9/java -XX:+UseParallelGC --module-path mods -m 122 $JDK9/java -XX:+UseParallelGC -p modlibs -m 121

Slide 12

Slide 12 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91 $JDK9/java -XX:+UseParallelGC --module-path mods -m 122 $JDK9/java -XX:+UseParallelGC -p modlibs -m 121 helloapp/bin/java -XX:+UseParallelGC -m 84

Slide 13

Slide 13 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91 $JDK9/java -XX:+UseParallelGC --module-path mods -m 122 $JDK9/java -XX:+UseParallelGC -p modlibs -m 121 helloapp/bin/java -XX:+UseParallelGC -m 84 $JDK9/java -XX:AOTLibrary=./aot/hello.so -XX:+UseParallelGC -m 124 $JDK9/java -XX:AOTLibrary=./aot/hello.so,./aot/libjava.base.so ... 135

Slide 14

Slide 14 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91 $JDK9/java -XX:+UseParallelGC --module-path mods -m 122 $JDK9/java -XX:+UseParallelGC -p modlibs -m 121 helloapp/bin/java -XX:+UseParallelGC -m 84 $JDK9/java -XX:AOTLibrary=./aot/hello.so -XX:+UseParallelGC -m 124 $JDK9/java -XX:AOTLibrary=./aot/hello.so,./aot/libjava.base.so ... 135 $JDK9/java -XX:+UseParallelGC -cp -Xshare:on 53

Slide 15

Slide 15 text

sudo perf stat -r50 "$@" Elapsed time, msec $JDK8/java -cp 55 $JDK8/java -jar 60 $JDK9/java -XX:+UseParallelGC -cp 81 $JDK9/java -XX:+UseParallelGC -jar 91 $JDK9/java -XX:+UseParallelGC --module-path mods -m 122 $JDK9/java -XX:+UseParallelGC -p modlibs -m 121 helloapp/bin/java -XX:+UseParallelGC -m 84 $JDK9/java -XX:AOTLibrary=./aot/hello.so -XX:+UseParallelGC -m 124 $JDK9/java -XX:AOTLibrary=./aot/hello.so,./aot/libjava.base.so ... 135 $JDK9/java -XX:+UseParallelGC -cp -Xshare:on 53 $JDK8/java -cp -Xshare:on 37

Slide 16

Slide 16 text

JEP 243: Java-Level JVM Compiler Interface

Slide 17

Slide 17 text

Summary Develop a Java based JVM compiler interface (JVMCI) enabling a compiler written in Java to be used by the JVM as a dynamic compiler. Goals ● Allow a Java component programmed against the JVMCI to be loaded at runtime and used by the JVM’s compile broker. ● Allow a Java component programmed against the JVMCI to be loaded at runtime and used by trusted Java code to install machine code in the JVM that can be called via a Java reference to the installed code.

Slide 18

Slide 18 text

JEP 248: Make G1 the Default Garbage Collector

Slide 19

Slide 19 text

● Default GC changed ● You are going to need JDK 10 (see [6] Why you want to run Java 10 if you're using the G1 Garbage Collector) ● Here be dragons (see [5] What a difference a JVM makes? )

Slide 20

Slide 20 text

JEP 254: Compact Strings

Slide 21

Slide 21 text

import org.openjdk.jol.info.ClassLayout; import org.openjdk.jol.info.GraphLayout; import org.openjdk.jol.vm.VM; import static java.lang.System.out; public class StringLayout { public static void main(String[] args) { String value = "Lorem ipsum ... est laborum."; out.println(VM.current().details()); out.println(ClassLayout.parseClass(String.class).toPrintable()); out.println(GraphLayout.parseInstance(value).toFootprint()); } }

Slide 22

Slide 22 text

JDK 8 java.lang.String object internals: OFFSET SIZE TYPE DESCRIPTION 0 12 (object header) 12 4 char[] String.value 16 4 int String.hash 20 4 (loss due to the next object alignment) Instance size: 24 bytes Space losses: 0 bytes internal + 4 bytes external = 4 bytes total java.lang.String@3d82c5f3d footprint: COUNT AVG SUM DESCRIPTION 1 912 912 [C 1 24 24 java.lang.String 2 936 (total)

Slide 23

Slide 23 text

JDK 9 java.lang.String object internals: OFFSET SIZE TYPE DESCRIPTION 0 12 (object header) 12 4 byte[] String.value 16 4 int String.hash 20 1 byte String.coder 21 3 (loss due to the next object alignment) Instance size: 24 bytes Space losses: 0 bytes internal + 3 bytes external = 3 bytes total java.lang.String@5e57643ed footprint: COUNT AVG SUM DESCRIPTION 1 464 464 [B 1 24 24 java.lang.String 2 488 (total)

Slide 24

Slide 24 text

public class StringBasicBenchmark { @Benchmark public void charAt(Blackhole bh) { String v = value; for (int i = 0, len = v.length(); i < len; i++) { bh.consume(v.charAt(i)); } } @Benchmark public String toLowerCase() { return value.toLowerCase(Locale.US); } @Benchmark public String substringHead() { return value.substring(0, substringIndex); } @Benchmark public String substringTail() { return value.substring(substringIndex); } }

Slide 25

Slide 25 text

Time, ns/op Allocations, B/op Benchmark (value) JDK 8 JDK 9 JDK 8 JDK 9 StringBasicBenchmark.charAt Java is awesome! 61.7 57.7 0 0 StringBasicBenchmark.charAt Java ᛠwesome! 60.0 58.4 0 0 StringBasicBenchmark.substringHead Java is awesome! 11.2 10.6 48 48 StringBasicBenchmark.substringHead Java ᛠwesome! 11.3 10.9 48 48 StringBasicBenchmark.substringTail Java is awesome! 13.9 12.6 64 56 StringBasicBenchmark.substringTail Java ᛠwesome! 13.3 18.8 64 96 StringBasicBenchmark.toLowerCase Java is awesome! 47.5 28.3 120 56 StringBasicBenchmark.toLowerCase Java ᛠwesome! 104.4 99.5 120 176

Slide 26

Slide 26 text

public class StringExtendedBenchmark { @Benchmark public int indexOf() { return value.indexOf(indexOf); } @Benchmark public boolean startsWith() { return value.startsWith(startsWith); } @Benchmark public boolean equals() { return value.equals(value2); } @Benchmark public int compareTo() { return value.compareTo(value2); } }

Slide 27

Slide 27 text

Time, ns/op Benchmark (value) (value2) JDK 8 JDK 9 StringExtendedBenchmark.indexOf Java is awesome! Java is awesome! 7.1 7.4 StringExtendedBenchmark.indexOf Java is awesome! Java ᛠwesome! 7.7 2.4 StringExtendedBenchmark.indexOf Java ᛠwesome! Java is awesome! 7.8 8.3 StringExtendedBenchmark.indexOf Java ᛠwesome! Java ᛠwesome! 7.1 7.3 StringExtendedBenchmark.startsWith Java is awesome! Java is awesome! 6.1 6.2 StringExtendedBenchmark.startsWith Java is awesome! Java ᛠwesome! 6.1 6.2 StringExtendedBenchmark.startsWith Java ᛠwesome! Java is awesome! 6.0 6.4 StringExtendedBenchmark.startsWith Java ᛠwesome! Java ᛠwesome! 6.1 6.4 StringExtendedBenchmark.compareTo Java is awesome! Java is awesome! 6.8 5.7 StringExtendedBenchmark.compareTo Java is awesome! Java ᛠwesome! 5.6 6.1 StringExtendedBenchmark.compareTo Java ᛠwesome! Java is awesome! 5.6 6.5 StringExtendedBenchmark.compareTo Java ᛠwesome! Java ᛠwesome! 6.8 7.3 StringExtendedBenchmark.equals Java is awesome! Java is awesome! 4.6 6.2 StringExtendedBenchmark.equals Java is awesome! Java ᛠwesome! 4.5 2.7 StringExtendedBenchmark.equals Java ᛠwesome! Java is awesome! 4.4 2.7 StringExtendedBenchmark.equals Java ᛠwesome! Java ᛠwesome! 4.6 5.0

Slide 28

Slide 28 text

public class StringMaxSize { public static void main(String[] args) { char[] data = new char[Integer.MAX_VALUE - 2]; data[0] = '\uD83D'; data[1] = '\uDC7B'; String value = new String(data); System.out.println(value.hashCode()); } } Exception in thread "main" java.lang.OutOfMemoryError: UTF16 String size is 2147483645, should be less than 1073741823 at java.base/java.lang.StringUTF16.newBytesFor(StringUTF16.java:46) at java.base/java.lang.StringUTF16.toBytes(StringUTF16.java:148) at java.base/java.lang.String.(String.java:3023) at java.base/java.lang.String.(String.java:249) at com.vyazelenko.perf.string.StringMaxSize.main(StringMaxSize.java:9)

Slide 29

Slide 29 text

JEP 280: Indify String Concatenation

Slide 30

Slide 30 text

import static java.lang.System.currentTimeMillis; import static java.lang.System.out; public class StringConcatExplore { public static void main(String[] args) { log("msg", 42); } private static void log(String msg, int count) { out.println("[" + currentTimeMillis() + "]: " + msg + " (" + count + ")"); } }

Slide 31

Slide 31 text

JDK 8 0: getstatic #4 // Field java/lang/System.out:Ljava/io/PrintStream; 3: new #5 // class java/lang/StringBuilder 6: dup 7: invokespecial #6 // Method java/lang/StringBuilder."":()V 10: ldc #7 // String [ 12: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 15: invokestatic #9 // Method java/lang/System.currentTimeMillis:()J 18: invokevirtual #10 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder; 21: ldc #11 // String ]: 23: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 26: aload_0 27: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 30: ldc #12 // String ( 32: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 35: iload_1 36: invokevirtual #13 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 39: ldc #14 // String ) 41: invokevirtual #8 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 44: invokevirtual #15 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 47: invokevirtual #16 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 50: return

Slide 32

Slide 32 text

JDK 9 0: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 3: invokestatic #8 // Method java/lang/System.currentTimeMillis:()J 6: aload_0 7: iload_1 8: invokedynamic #9, 0 // InvokeDynamic #0:makeConcatWithConstants:(JLjava/lang/String;I)Ljava/lang/String; 13: invokevirtual #10 // Method java/io/PrintStream.println:(Ljava/lang/String;)V 16: return BootstrapMethods: 0: #44 REF_invokeStatic java/lang/invoke/StringConcatFactory.makeConcatWithConstants: (Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/invoke/MethodType;Ljava/lang/String; [Ljava/lang/Object;)Ljava/lang/invoke/CallSite; Method arguments: #45 [\u0001]: \u0001 (\u0001)

Slide 33

Slide 33 text

public class StringConcatBenchmark { private long currentTime; private int count; private String message; @Setup public void setup() { currentTime = System.currentTimeMillis(); count = 42; message = "Log payload"; } @Benchmark public String log() { return "[" + currentTime + "]: " + message + " (" + count + ")"; } }

Slide 34

Slide 34 text

StringConcatBenchmark.log Time, ns/op Allocations, B/op JDK 8 101.2 272 JDK 9 36.4 80 JDK 9: -XX:-CompactStrings 38.7 112 JDK 9: -Djava.lang.invoke.stringConcat=BC_SB 71.7 192 JDK 9: -Djava.lang.invoke.stringConcat=BC_SB_SIZED 62.1 176 JDK 9: -Djava.lang.invoke.stringConcat=BC_SB_SIZED_EXACT 52.9 160 JDK 9: -Djava.lang.invoke.stringConcat=MH_SB_SIZED 65.4 176 JDK 9: -Djava.lang.invoke.stringConcat=MH_SB_SIZED_EXACT 66.3 216

Slide 35

Slide 35 text

public class StringConcatLoopBenchmark { @Benchmark public String naive() { String result = ""; for (int i = 0; i < iterations; i++) { result += (i + " " + log() + "\n"); } return result; } @Benchmark public String proper() { StringBuilder sb = new StringBuilder(); for (int i = 0; i < iterations; i++) { sb.append(i).append(" ").append(log()).append("\n"); } return sb.toString(); } }

Slide 36

Slide 36 text

Time, us/op Allocations, B/op Benchmark JDK 8 JDK 9 JDK 8 JDK 9 StringConcatLoopBenchmark.naive 36.2 5.2 384288 52880 StringConcatLoopBenchmark.proper 6.9 2.9 26496 10328 5x 1.8x 15x 5x

Slide 37

Slide 37 text

JEP 269: Convenience Factory Methods for Collections

Slide 38

Slide 38 text

public class LayoutIntrospection { public static void main(String[] args) { footprint(List.of()); footprint(List.of(1)); footprint(List.of(1, 2)); ... footprint(Set.of(1)); footprint(Set.of(1, 2)); ... footprint(Map.of(1, 1)); footprint(Map.of(1, 1, 2, 2)); footprint(Map.ofEntries(Map.entry(1, 1), Map.entry(2, 2))); } }

Slide 39

Slide 39 text

Footprint, B Payload, B Overhead, % List.of() 16 0 - Collections.emptyList() 16 0 - List.of(1) 40 16 60 Collections.singletonList(1) 40 16 60 new ArrayList<>(1) 64 16 75 new LinkedList<>(1) 72 16 78 List.of(1,2) 56 32 43 new ArrayList<>(1,2) 80 32 60 new LinkedList<>(1,2) 112 32 71 List.of(1..10) 240 160 33 new ArrayList<>(1..10) 240 160 33 new LinkedList<>(1..10) 432 160 63

Slide 40

Slide 40 text

Footprint, B Payload, B Overhead, % Set.of() 16 0 - Collections.emptySet() 16 0 - Set.of(1) 32 16 50 Collections.singleton(1) 32 16 50 new HashSet<>(1) 208 16 92 new LinkedHashSet<>(1) 224 16 93 new TreeSet<>(1) 136 16 88 Set.of(1,2) 56 32 43 new HashSet<>(1,2) 256 32 88 new LinkedHashSet<>(1,2) 280 32 89 new TreeSet<>(1,2) 192 32 83 Set.of(1..10) 280 160 43 new HashSet<>(1..10) 640 160 75 new LinkedHashSet<>(1..10) 792 160 80 new TreeSet<>(1..10) 640 160 75

Slide 41

Slide 41 text

Footprint, B Payload, B Overhead, % Map.of() 24 0 - Collections.emptyMap() 24 0 - Map.of(1,1) 48 16 67 Collections.singletonMap(1,1) 56 16 71 new HashMap<>(1,1) 120 16 87 new LinkedHashMap<>(1,1) 136 16 88 new TreeMap<>(1,1) 104 16 85 Map.of(1,1,2,2) 112 32 71 new HashMap<>(1,1,2,2) 176 32 82 new LinkedHashMap<>(1,1,2,2) 200 32 84 new TreeMap<>(1,1,2,2) 160 32 80 Map.of(1,1..10,10) 368 160 57 new HashMap<>(1,1..10,10) 608 160 74 new LinkedHashMap<>(1,1..10,10) 696 160 77 new TreeMap<>(1,1..10,10) 608 160 74 Map.ofEntries(collidingEntries(16)) 816 512 37 new HashMap<>(collidingEntries(16)) 1728 512 70 new LinkedHashMap<>(collidingEntries(16)) 1736 512 71 new TreeMap<>(collidingEntries(16)) 1200 512 57

Slide 42

Slide 42 text

public class ListBenchmark extends AbstractCollectionBenchmark { @Benchmark public Object get() { return list.get(index); } @Benchmark public Object contains() { return list.contains(contains); } @Benchmark public void iterator(Blackhole bh) { List list = this.list; for (Object o : list) { bh.consume(o); } } }

Slide 43

Slide 43 text

Benchmark (kind) (size) Time, ns/op ListBenchmark.contains List.of 1 3.5 ListBenchmark.contains List.of 2 4.1 ListBenchmark.contains List.of 10 8.6 ListBenchmark.contains List.of 100 34.8 ListBenchmark.contains ArrayList 1 4.1 ListBenchmark.contains ArrayList 2 5.2 ListBenchmark.contains ArrayList 10 8.7 ListBenchmark.contains ArrayList 100 33.7 ListBenchmark.contains LinkedList 1 3.9 ListBenchmark.contains LinkedList 2 5.1 ListBenchmark.contains LinkedList 10 10.1 ListBenchmark.contains LinkedList 100 97.2

Slide 44

Slide 44 text

public class SetBenchmark extends AbstractCollectionBenchmark { @Benchmark public Object contains() { return set.contains(contains); } @Benchmark public void iterator(Blackhole bh) { Set list = this.set; for (Object o : list) { bh.consume(o); } } }

Slide 45

Slide 45 text

Benchmark (kind) (size) Time, ns/op SetBenchmark.contains Set.of 1 3.5 SetBenchmark.contains Set.of 2 3.6 SetBenchmark.contains Set.of 10 11.8 SetBenchmark.contains Set.of 100 12.1 SetBenchmark.contains HashSet 1 6.8 SetBenchmark.contains HashSet 2 6.9 SetBenchmark.contains HashSet 10 7.3 SetBenchmark.contains HashSet 100 8.1 SetBenchmark.contains LinkedHashSet 1 6.8 SetBenchmark.contains LinkedHashSet 2 6.8 SetBenchmark.contains LinkedHashSet 10 6.9 SetBenchmark.contains LinkedHashSet 100 8.1 SetBenchmark.contains TreeSet 1 4.3 SetBenchmark.contains TreeSet 2 4.8 SetBenchmark.contains TreeSet 10 7.1 SetBenchmark.contains TreeSet 100 13.5

Slide 46

Slide 46 text

JEP 259: Stack-Walking API

Slide 47

Slide 47 text

public class ExceptionBenchmark { @Benchmark public Class> callerClass() throws Exception { return doCall(() -> { StackTraceElement[] stackTrace = new Exception().getStackTrace(); return Class.forName(stackTrace[2].getClassName()); }, stackDepth); } @Benchmark public int stackDepth() throws Exception { return doCall(() -> new Exception().getStackTrace().length, stackDepth); } @Benchmark public Object top10frames() throws Exception { return doCall(() -> { StackTraceElement[] stackTrace = new Exception().getStackTrace(); return Arrays.copyOfRange(stackTrace, 0, 10); }, stackDepth); } }

Slide 48

Slide 48 text

public class StackWalkerBenchmark { public static final StackWalker STACK_WALKER = StackWalker.getInstance(Option.RETAIN_CLASS_REFERENCE); @Benchmark public Class> callerClass() throws Exception { return doCall(() -> STACK_WALKER.getCallerClass(), stackDepth); } @Benchmark public int stackDepth() throws Exception { return doCall( () -> STACK_WALKER.walk(stream -> stream.count()).intValue(), stackDepth); } @Benchmark public Object top10frames() throws Exception { return doCall( () -> STACK_WALKER.walk(s -> s.limit(10).collect(toList())), stackDepth); } }

Slide 49

Slide 49 text

Benchmark (stackSize) Time, us/op ExceptionBenchmark.callerClass 10 16.6 ExceptionBenchmark.callerClass 100 54.1 ExceptionBenchmark.stackDepth 10 16.0 ExceptionBenchmark.stackDepth 100 53.8 ExceptionBenchmark.top10frames 10 16.3 ExceptionBenchmark.top10frames 100 54.3 StackWalkerBenchmark.callerClass 10 0.7 StackWalkerBenchmark.callerClass 100 0.8 StackWalkerBenchmark.stackDepth 10 7.8 StackWalkerBenchmark.stackDepth 100 30.3 StackWalkerBenchmark.top10frames 10 5.2 StackWalkerBenchmark.top10frames 100 5.2

Slide 50

Slide 50 text

New APIs

Slide 51

Slide 51 text

java.lang.Math#fma(double, double, double) java.lang.Math#fma(float, float, float) java.util.Objects#checkIndex(int, int) java.util.Objects#checkFromToIndex(int, int, int) java.util.Objects#checkFromIndexSize(int, int, int) java.util.Arrays#compare(int[], int[]) java.util.Arrays#compare(int[], int, int, int[], int, int) java.util.Arrays#compareUnsigned(int[], int[]) java.util.Arrays#compareUnsigned(int[], int, int, int[], int, int) java.util.Arrays#equals(int[], int, int, int[], int, int) java.util.Arrays#mismatch(int[], int[]) java.util.Arrays#mismatch(int[], int, int, int[], int, int) // + for all primitive types + Object[]

Slide 52

Slide 52 text

public class ArraysBenchmark { @Benchmark public int builtin() { return Arrays.mismatch(a, b); } @Benchmark public int handRolled() { byte[] a = this.a; byte[] b = this.b; int length = Math.min(a.length, b.length); for (int i = 0; i < length; i++) { if (a[i] != b[i]) { return i; } } return a.length == b.length ? -1 : length; } }

Slide 53

Slide 53 text

Benchmark (prefixSize) Time, ns/op ArraysBenchmark.handRolled 10 6.8 ArraysBenchmark.handRolled 100 32.7 ArraysBenchmark.handRolled 1000 295.5 ArraysBenchmark.handRolled 10000 2925.3 ArraysBenchmark.builtin 10 6.4 ArraysBenchmark.builtin 100 8.5 ArraysBenchmark.builtin 1000 24.7 ArraysBenchmark.builtin 10000 231.8

Slide 54

Slide 54 text

Recap ● New Java release every 6 month ● Not all releases created equal: LTS vs non-LTS ● JDK 9 has lots of exciting performance features ● JDK 10 is bringing even more

Slide 55

Slide 55 text

References 1) https://github.com/vyazelenko/performance-after-eight 2) http://openjdk.java.net/projects/jdk9/ 3) http://openjdk.java.net/projects/jdk/10/ 4) https://www.azul.com/java-stable-secure-free-choose-two-three/ 5) http://psy-lob-saw.blogspot.ch/2018/01/what-diference-jvm-makes.html 6) https://www.opsian.com/blog/java-10-with-g1/ 7) http://openjdk.java.net/projects/code-tools/jmh/ 8) http://openjdk.java.net/projects/code-tools/jol/

Slide 56

Slide 56 text

Questions? @DVyazelenko