Created
September 6, 2023 23:13
-
-
Save Groostav/8420ba6a61004617d6f1643b4ade9a85 to your computer and use it in GitHub Desktop.
attempting to performance profile forms java switch expressions
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
7:10:36 p.m.: Executing 'jmh'... | |
> Task :compileKotlin NO-SOURCE | |
> Task :compileJava UP-TO-DATE | |
> Task :processResources NO-SOURCE | |
> Task :classes UP-TO-DATE | |
> Task :compileJmhKotlin NO-SOURCE | |
> Task :compileJmhJava UP-TO-DATE | |
> Task :processJmhResources NO-SOURCE | |
> Task :jmhClasses UP-TO-DATE | |
> Task :jmh | |
# JMH version: 1.35 | |
# VM version: JDK 20.0.2, OpenJDK 64-Bit Server VM, 20.0.2+9 | |
# VM invoker: C:\Program Files\Zulu\zulu-20\bin\java.exe | |
# VM options: --enable-preview --enable-preview -Dfile.encoding=windows-1252 -Duser.country=CA -Duser.language=en -Duser.variant | |
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) | |
# Warmup: 5 iterations, 5 s each | |
# Measurement: 5 iterations, 1 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: org.example.SwitchBenchmarks.measureJavaIntSwitchExpression | |
# Run progress: 0.00% complete, ETA 00:02:00 | |
# Fork: 1 of 1 | |
# Warmup Iteration 1: 28.824 ops/us | |
# Warmup Iteration 2: 29.548 ops/us | |
# Warmup Iteration 3: 29.714 ops/us | |
# Warmup Iteration 4: 29.228 ops/us | |
# Warmup Iteration 5: 29.668 ops/us | |
Iteration 1: 29.315 ops/us | |
Iteration 2: 29.829 ops/us | |
Iteration 3: 29.736 ops/us | |
Iteration 4: 29.971 ops/us | |
Iteration 5: 29.768 ops/us | |
Result "org.example.SwitchBenchmarks.measureJavaIntSwitchExpression": | |
29.724 �(99.9%) 0.946 ops/us [Average] | |
(min, avg, max) = (29.315, 29.724, 29.971), stdev = 0.246 | |
CI (99.9%): [28.778, 30.670] (assumes normal distribution) | |
# JMH version: 1.35 | |
# VM version: JDK 20.0.2, OpenJDK 64-Bit Server VM, 20.0.2+9 | |
# VM invoker: C:\Program Files\Zulu\zulu-20\bin\java.exe | |
# VM options: --enable-preview --enable-preview -Dfile.encoding=windows-1252 -Duser.country=CA -Duser.language=en -Duser.variant | |
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) | |
# Warmup: 5 iterations, 5 s each | |
# Measurement: 5 iterations, 1 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: org.example.SwitchBenchmarks.measureJavaIntSwitchStatement | |
# Run progress: 25.00% complete, ETA 00:01:31 | |
# Fork: 1 of 1 | |
# Warmup Iteration 1: 29.073 ops/us | |
# Warmup Iteration 2: 29.402 ops/us | |
# Warmup Iteration 3: 28.820 ops/us | |
# Warmup Iteration 4: 28.138 ops/us | |
# Warmup Iteration 5: 28.804 ops/us | |
Iteration 1: 29.439 ops/us | |
Iteration 2: 29.482 ops/us | |
Iteration 3: 29.721 ops/us | |
Iteration 4: 29.550 ops/us | |
Iteration 5: 29.875 ops/us | |
Result "org.example.SwitchBenchmarks.measureJavaIntSwitchStatement": | |
29.613 �(99.9%) 0.699 ops/us [Average] | |
(min, avg, max) = (29.439, 29.613, 29.875), stdev = 0.182 | |
CI (99.9%): [28.914, 30.312] (assumes normal distribution) | |
# JMH version: 1.35 | |
# VM version: JDK 20.0.2, OpenJDK 64-Bit Server VM, 20.0.2+9 | |
# VM invoker: C:\Program Files\Zulu\zulu-20\bin\java.exe | |
# VM options: --enable-preview --enable-preview -Dfile.encoding=windows-1252 -Duser.country=CA -Duser.language=en -Duser.variant | |
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) | |
# Warmup: 5 iterations, 5 s each | |
# Measurement: 5 iterations, 1 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: org.example.SwitchBenchmarks.measureJavaTypeIfInstanceofElseIf | |
# Run progress: 50.00% complete, ETA 00:01:00 | |
# Fork: 1 of 1 | |
# Warmup Iteration 1: 32.371 ops/us | |
# Warmup Iteration 2: 32.975 ops/us | |
# Warmup Iteration 3: 32.449 ops/us | |
# Warmup Iteration 4: 33.227 ops/us | |
# Warmup Iteration 5: 32.538 ops/us | |
Iteration 1: 33.297 ops/us | |
Iteration 2: 33.607 ops/us | |
Iteration 3: 33.757 ops/us | |
Iteration 4: 33.529 ops/us | |
Iteration 5: 33.677 ops/us | |
Result "org.example.SwitchBenchmarks.measureJavaTypeIfInstanceofElseIf": | |
33.573 �(99.9%) 0.679 ops/us [Average] | |
(min, avg, max) = (33.297, 33.573, 33.757), stdev = 0.176 | |
CI (99.9%): [32.894, 34.252] (assumes normal distribution) | |
# JMH version: 1.35 | |
# VM version: JDK 20.0.2, OpenJDK 64-Bit Server VM, 20.0.2+9 | |
# VM invoker: C:\Program Files\Zulu\zulu-20\bin\java.exe | |
# VM options: --enable-preview --enable-preview -Dfile.encoding=windows-1252 -Duser.country=CA -Duser.language=en -Duser.variant | |
# Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable) | |
# Warmup: 5 iterations, 5 s each | |
# Measurement: 5 iterations, 1 s each | |
# Timeout: 10 min per iteration | |
# Threads: 1 thread, will synchronize iterations | |
# Benchmark mode: Throughput, ops/time | |
# Benchmark: org.example.SwitchBenchmarks.measureJavaTypeSwitchExpression | |
# Run progress: 75.00% complete, ETA 00:00:30 | |
# Fork: 1 of 1 | |
# Warmup Iteration 1: 31.236 ops/us | |
# Warmup Iteration 2: 31.416 ops/us | |
# Warmup Iteration 3: 31.731 ops/us | |
# Warmup Iteration 4: 31.995 ops/us | |
# Warmup Iteration 5: 31.591 ops/us | |
Iteration 1: 31.947 ops/us | |
Iteration 2: 31.630 ops/us | |
Iteration 3: 30.647 ops/us | |
Iteration 4: 31.658 ops/us | |
Iteration 5: 31.281 ops/us | |
Result "org.example.SwitchBenchmarks.measureJavaTypeSwitchExpression": | |
31.433 �(99.9%) 1.920 ops/us [Average] | |
(min, avg, max) = (30.647, 31.433, 31.947), stdev = 0.499 | |
CI (99.9%): [29.512, 33.353] (assumes normal distribution) | |
# Run complete. Total time: 00:02:01 | |
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on | |
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial | |
experiments, perform baseline and negative tests that provide experimental control, make sure | |
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts. | |
Do not assume the numbers tell you what you want them to tell. | |
NOTE: Current JVM experimentally supports Compiler Blackholes, and they are in use. Please exercise | |
extra caution when trusting the results, look into the generated code to check the benchmark still | |
works, and factor in a small probability of new VM bugs. Additionally, while comparisons between | |
different JVMs are already problematic, the performance difference caused by different Blackhole | |
modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons. | |
Benchmark Mode Cnt Score Error Units | |
SwitchBenchmarks.measureJavaIntSwitchExpression thrpt 5 29.724 � 0.946 ops/us | |
SwitchBenchmarks.measureJavaIntSwitchStatement thrpt 5 29.613 � 0.699 ops/us | |
SwitchBenchmarks.measureJavaTypeIfInstanceofElseIf thrpt 5 33.573 � 0.679 ops/us | |
SwitchBenchmarks.measureJavaTypeSwitchExpression thrpt 5 31.433 � 1.920 ops/us | |
Deprecated Gradle features were used in this build, making it incompatible with Gradle 9.0. | |
You can use '--warning-mode all' to show the individual deprecation warnings and determine if they come from your own scripts or plugins. | |
For more on this, please refer to https://docs.gradle.org/8.3/userguide/command_line_interface.html#sec:command_line_warnings in the Gradle documentation. | |
BUILD SUCCESSFUL in 2m 2s | |
3 actionable tasks: 1 executed, 2 up-to-date | |
7:12:39 p.m.: Execution finished 'jmh'. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package org.example; | |
import org.openjdk.jmh.annotations.*; | |
import java.util.concurrent.TimeUnit; | |
@BenchmarkMode(Mode.Throughput) | |
@OutputTimeUnit(TimeUnit.MICROSECONDS) | |
@Warmup(iterations = 5, time = 5) | |
@Measurement(iterations = 5, time = 1) | |
@Fork(1) | |
@State(Scope.Benchmark) | |
public class JavaJHMBenchmarks { | |
@State(Scope.Thread) | |
public static class MyState { | |
public final Node[] nodes = new Node[]{ | |
new Node.FirstNodeType(0), | |
new Node.SecondNodetype("one"), | |
new Node.ThirdNodeType(2.0f), | |
new Node.FourthNodeType(3L) | |
}; | |
@Setup(Level.Invocation) | |
public void reallyFastSetup(){ | |
node = nodes[index]; | |
index += 1; | |
if(index >= nodes.length) index -= nodes.length; | |
} | |
private int index; | |
public Node node; | |
public Object result; | |
} | |
@Benchmark | |
public void measureJavaTypeSwitchExpression(MyState state) { | |
// this is by far the most elegant | |
state.result = switch (state.node){ | |
case Node.FirstNodeType first -> first.id(); //warning: boxing | |
case Node.SecondNodetype second -> second.name(); | |
case Node.ThirdNodeType third -> third.decimal(); | |
case Node.FourthNodeType fourth -> fourth.bits(); | |
}; | |
} | |
@Benchmark | |
public void measureJavaTypeIfInstanceofElseIf(MyState state){ | |
var node = state.node; | |
Object result = null; | |
if(node instanceof Node.FirstNodeType first){ | |
result = first.id(); | |
} | |
else if (node instanceof Node.SecondNodetype second){ | |
result = second.name(); | |
} | |
else if (node instanceof Node.ThirdNodeType third){ | |
result = third.decimal(); | |
} | |
else if (node instanceof Node.FourthNodeType fourth){ | |
result = fourth.bits(); | |
} | |
state.result = result; | |
} | |
@Benchmark | |
public void measureJavaIntSwitchStatement(MyState state){ | |
var node = state.node; | |
Object result = null; | |
switch(node.typeInt()){ | |
case 0: result = ((Node.FirstNodeType) node).id(); break; | |
case 1: result = ((Node.SecondNodetype) node).name(); break; | |
case 2: result = ((Node.ThirdNodeType) node).decimal(); break; | |
case 3: result = ((Node.FourthNodeType) node).bits(); break; | |
} | |
state.result = result; | |
} | |
@Benchmark | |
public void measureJavaIntSwitchExpression(MyState state){ | |
var node = state.node; | |
Object result = switch(node.typeInt()){ | |
case 0 -> ((Node.FirstNodeType) node).id(); | |
case 1 -> ((Node.SecondNodetype) node).name(); | |
case 2 -> ((Node.ThirdNodeType) node).decimal(); | |
case 3 -> ((Node.FourthNodeType) node).bits(); | |
default -> throw new UnsupportedOperationException(); | |
}; | |
state.result = result; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment