Skip to content

Instantly share code, notes, and snippets.

@xuwei-k
Last active December 12, 2025 11:30
Show Gist options
  • Select an option

  • Save xuwei-k/1775f8046f76e66d54e124e91804c431 to your computer and use it in GitHub Desktop.

Select an option

Save xuwei-k/1775f8046f76e66d54e124e91804c431 to your computer and use it in GitHub Desktop.
// a2/src/main/scala/Bench.scala
package example
import org.openjdk.jmh.annotations.Benchmark
class Bench {
inline final def limit: Int = 100
@Benchmark
def release8(): Int = {
var i = 0
var sum = 0
while (i < limit) {
sum += Release8.f(
i % 2 == 0,
i.toByte,
i.toShort,
i,
i,
i.toFloat,
i,
i.toString,
i.toChar
).length
i += 1
}
sum
}
@Benchmark
def release11(): Int = {
var i = 0
var sum = 0
while (i < limit) {
sum += Release11.f(
i % 2 == 0,
i.toByte,
i.toShort,
i,
i,
i.toFloat,
i,
i.toString,
i.toChar
).length
i += 1
}
sum
}
}
sbt.version=1.11.7
val common = Def.settings(
scalaVersion := "3.7.4",
)
def src(objectName: String): String = {
Seq(
s"""package example
object ${objectName} {""",
"""
def f(
x1: Boolean,
x2: Byte,
x3: Short,
x4: Int,
x5: Long,
x6: Float,
x7: Double,
x8: String,
x9: Char,
): String = {
val a1 = s" $x1 $x2 $x3 $x4 $x5 $x6 $x7 $x8 $x9 "
s" $x1 $a1 $x2 $a1 $x3 $a1 $x4 $a1 $x5 $a1 $x6 $a1 $x7 $a1 $x8 $a1 $x9 "
}
}
"""
).mkString("\n")
}
def sourceGen(objectName: String) =
Compile / sourceGenerators += task {
val f = (Compile / sourceManaged).value / s"${objectName}.scala"
IO.write(f, src(objectName))
Seq(f)
}
val a1 = project
.settings(
scalacOptions += "-release:11",
sourceGen("Release11"),
common
)
val a2 = project
.enablePlugins(JmhPlugin)
.settings(
scalacOptions += "-release:8",
sourceGen("Release8"),
common
)
.dependsOn(a1)
public java.lang.String f(boolean, byte, short, int, long, float, double, java.lang.String, char);
descriptor: (ZBSIJFDLjava/lang/String;C)Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=19, locals=13, args_size=10
0: iload_1
1: iload_2
2: iload_3
3: iload 4
5: lload 5
7: fload 7
9: dload 8
11: aload 10
13: iload 11
15: invokedynamic #52, 0 // InvokeDynamic #0:makeConcatWithConstants:(ZBSIJFDLjava/lang/String;C)Ljava/lang/String;
20: astore 12
22: iload_1
23: aload 12
25: iload_2
26: aload 12
28: iload_3
29: aload 12
31: iload 4
33: aload 12
35: lload 5
37: aload 12
39: fload 7
41: aload 12
43: dload 8
45: aload 12
47: aload 10
49: aload 12
51: iload 11
53: invokedynamic #57, 0 // InvokeDynamic #1:makeConcatWithConstants:(ZLjava/lang/String;BLjava/lang/String;SLjava/lang/String;ILjava/lang/String;JLjava/lang/String;FLjava/lang/String;DLjava/lang/String;Ljava/lang/String;Ljava/lang/String;C)Ljava/lang/String;
58: areturn
public java.lang.String f(boolean, byte, short, int, long, float, double, java.lang.String, char);
descriptor: (ZBSIJFDLjava/lang/String;C)Ljava/lang/String;
flags: (0x0001) ACC_PUBLIC
Code:
stack=3, locals=13, args_size=10
0: new #38 // class java/lang/StringBuilder
3: dup
4: ldc #39 // int 10
6: invokespecial #42 // Method java/lang/StringBuilder."<init>":(I)V
9: ldc #44 // String
11: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
14: iload_1
15: invokevirtual #51 // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
18: ldc #44 // String
20: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
23: iload_2
24: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
27: ldc #44 // String
29: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
32: iload_3
33: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
36: ldc #44 // String
38: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
41: iload 4
43: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
46: ldc #44 // String
48: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
51: lload 5
53: invokevirtual #57 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
56: ldc #44 // String
58: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
61: fload 7
63: invokevirtual #60 // Method java/lang/StringBuilder.append:(F)Ljava/lang/StringBuilder;
66: ldc #44 // String
68: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
71: dload 8
73: invokevirtual #63 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
76: ldc #44 // String
78: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
81: aload 10
83: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
86: ldc #44 // String
88: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
91: iload 11
93: invokevirtual #66 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
96: ldc #44 // String
98: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
101: invokevirtual #70 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
104: astore 12
106: new #38 // class java/lang/StringBuilder
109: dup
110: ldc #71 // int 18
112: invokespecial #42 // Method java/lang/StringBuilder."<init>":(I)V
115: ldc #44 // String
117: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
120: iload_1
121: invokevirtual #51 // Method java/lang/StringBuilder.append:(Z)Ljava/lang/StringBuilder;
124: ldc #44 // String
126: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
129: aload 12
131: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
134: ldc #44 // String
136: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
139: iload_2
140: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
143: ldc #44 // String
145: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
148: aload 12
150: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
153: ldc #44 // String
155: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
158: iload_3
159: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
162: ldc #44 // String
164: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
167: aload 12
169: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
172: ldc #44 // String
174: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
177: iload 4
179: invokevirtual #54 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder;
182: ldc #44 // String
184: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
187: aload 12
189: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
192: ldc #44 // String
194: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
197: lload 5
199: invokevirtual #57 // Method java/lang/StringBuilder.append:(J)Ljava/lang/StringBuilder;
202: ldc #44 // String
204: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
207: aload 12
209: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
212: ldc #44 // String
214: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
217: fload 7
219: invokevirtual #60 // Method java/lang/StringBuilder.append:(F)Ljava/lang/StringBuilder;
222: ldc #44 // String
224: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
227: aload 12
229: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
232: ldc #44 // String
234: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
237: dload 8
239: invokevirtual #63 // Method java/lang/StringBuilder.append:(D)Ljava/lang/StringBuilder;
242: ldc #44 // String
244: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
247: aload 12
249: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
252: ldc #44 // String
254: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
257: aload 10
259: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
262: ldc #44 // String
264: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
267: aload 12
269: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
272: ldc #44 // String
274: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
277: iload 11
279: invokevirtual #66 // Method java/lang/StringBuilder.append:(C)Ljava/lang/StringBuilder;
282: ldc #44 // String
284: invokevirtual #48 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder;
287: invokevirtual #70 // Method java/lang/StringBuilder.toString:()Ljava/lang/String;
290: areturn
addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.8")
a2 main > Jmh/run -i 5 -wi 5 -f1 -t1
[info] running (fork) org.openjdk.jmh.Main -i 5 -wi 5 -f1 -t1
[info] # JMH version: 1.37
[info] # VM version: JDK 21.0.9, OpenJDK 64-Bit Server VM, 21.0.9+10-LTS
[info] # VM invoker: /Users/kenji/.sdkman/candidates/java/21.0.9-amzn/bin/java
[info] # VM options: <none>
[info] # Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
[info] # Warmup: 5 iterations, 10 s each
[info] # Measurement: 5 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: example.Bench.release11
[info] # Run progress: 0.00% complete, ETA 00:03:20
[info] # Fork: 1 of 1
[info] # Warmup Iteration 1: 42147.412 ops/s
[info] # Warmup Iteration 2: 41367.195 ops/s
[info] # Warmup Iteration 3: 42604.134 ops/s
[info] # Warmup Iteration 4: 42821.657 ops/s
[info] # Warmup Iteration 5: 43027.407 ops/s
[info] Iteration 1: 43065.151 ops/s
[info] Iteration 2: 43077.944 ops/s
[info] Iteration 3: 43320.732 ops/s
[info] Iteration 4: 43110.252 ops/s
[info] Iteration 5: 43427.503 ops/s
[info] Result "example.Bench.release11":
[info] 43200.316 ±(99.9%) 631.171 ops/s [Average]
[info] (min, avg, max) = (43065.151, 43200.316, 43427.503), stdev = 163.913
[info] CI (99.9%): [42569.146, 43831.487] (assumes normal distribution)
[info] # JMH version: 1.37
[info] # VM version: JDK 21.0.9, OpenJDK 64-Bit Server VM, 21.0.9+10-LTS
[info] # VM invoker: /Users/kenji/.sdkman/candidates/java/21.0.9-amzn/bin/java
[info] # VM options: <none>
[info] # Blackhole mode: compiler (auto-detected, use -Djmh.blackhole.autoDetect=false to disable)
[info] # Warmup: 5 iterations, 10 s each
[info] # Measurement: 5 iterations, 10 s each
[info] # Timeout: 10 min per iteration
[info] # Threads: 1 thread, will synchronize iterations
[info] # Benchmark mode: Throughput, ops/time
[info] # Benchmark: example.Bench.release8
[info] # Run progress: 50.00% complete, ETA 00:01:40
[info] # Fork: 1 of 1
[info] # Warmup Iteration 1: 28674.787 ops/s
[info] # Warmup Iteration 2: 28865.500 ops/s
[info] # Warmup Iteration 3: 28848.062 ops/s
[info] # Warmup Iteration 4: 28784.413 ops/s
[info] # Warmup Iteration 5: 28649.526 ops/s
[info] Iteration 1: 28838.453 ops/s
[info] Iteration 2: 28788.429 ops/s
[info] Iteration 3: 28600.508 ops/s
[info] Iteration 4: 28948.695 ops/s
[info] Iteration 5: 28965.212 ops/s
[info] Result "example.Bench.release8":
[info] 28828.259 ±(99.9%) 567.306 ops/s [Average]
[info] (min, avg, max) = (28600.508, 28828.259, 28965.212), stdev = 147.328
[info] CI (99.9%): [28260.953, 29395.566] (assumes normal distribution)
[info] # Run complete. Total time: 00:03:20
[info] REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
[info] why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
[info] experiments, perform baseline and negative tests that provide experimental control, make sure
[info] the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
[info] Do not assume the numbers tell you what you want them to tell.
[info] NOTE: Current JVM experimentally supports Compiler Blackholes, and they are in use. Please exercise
[info] extra caution when trusting the results, look into the generated code to check the benchmark still
[info] works, and factor in a small probability of new VM bugs. Additionally, while comparisons between
[info] different JVMs are already problematic, the performance difference caused by different Blackhole
[info] modes can be very significant. Please make sure you use the consistent Blackhole mode for comparisons.
[info] Benchmark Mode Cnt Score Error Units
[info] Bench.release11 thrpt 5 43200.316 ± 631.171 ops/s
[info] Bench.release8 thrpt 5 28828.259 ± 567.306 ops/s
[success] Total time: 201 s (0:03:21.0), completed Dec 12, 2025, 11:26:24 AM
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment