hminle hminle - 2 months ago 19
Scala Question

JMH Micro Benchmark Annotations with Scala

I am a newbie to JMH. I don't really understand how it work after running my code and using different annotations.
I use iteration = 1, warmup = 1, fork =1 in order to see my code will be executed one time, but it's not. JMH run my code more than 100,000 times, and I don't know why. So, how can I control the number of time my code called?
Here is my code: (I fix JMHSample_01 for my test)

package org.openjdk.jmh.samples
import java.util.concurrent.TimeUnit
import org.openjdk.jmh.annotations._
@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Array(Mode.AverageTime))
@State(Scope.Thread)
@Warmup(iterations = 1, time = 1)
@Measurement(iterations = 1, time = 1)
@Fork(1)
class JMHSample_01_HelloWorld {

@Benchmark
def wellHelloThere(): Unit = {
// this method was intentionally left blank.
val a:Int = 1
val b:Int = 2
val c:Int = a + b
println("this is c " + c)
}

}

Answer

This is how JMH works: it executes your code a dozen of times to find out what the average execution time is. A Java program needs to be run many times before the Java JIT-compiler optimizes a code. The benchmark tricks the JIT compiler to consider a benchmark method to be important in order to optimize it properly.

Your benchmark has many problems: it is deterministric where 1 + 2 is always 3 if this is what you want to measure: it will simply replace the computation with the end result.

Please look at the JMH samples to learn how to use JMH properly. In this context, it does not play much of a role that your benchmarks are written in Scala as it compiles down to Java byte code.