I'm using JMH and I find something hard to understand: I have one method annotated with @Benchmark
and I set measurementIterations(3)
. The method is called 3 times, but within each iteration call, the function runs a rather big and random number of times.
My question is: is that number completely random? Is there a way to control it and determine how many times should the function run within an iteration? And what is the importance with set up the measurementIterations
if each way or another, the function will run a random number of times?
There are two ways to run the JMH benchmark, uses Maven or run it via a JMH Runner class directly. 3.1 Maven, package it as a JAR and run it via org. openjdk.
JMH is short for Java Microbenchmark Harness. JMH is a toolkit that helps you implement Java microbenchmarks correctly. JMH is developed by the same people who implement the Java virtual machine, so these guys know what they are doing.
org.openjdk.jmh.annotations Fork annotation allows to set the default forking parameters for the benchmark. This annotation may be put at Benchmark method to have effect on that method only, or at the enclosing class instance to have the effect over all Benchmark methods in the class.
This dedicates 3 full iterations as warmup each running for 2 seconds. Having seen the theory and terminology of a JMH project and JMH benchmark, let us benchmark code and see the results. In Java, String concatenation is costly as it creates new String instances when concatenation as Strings are immutable.
The JMH benchmark is run for a number of trials. Trials are also called as forks. For each fork, a number of iterations are configured as warmups. This is to get the JVM to warmup the code we are measuring. This is important to avoid fluctuations or variations in the runtime once we start the actual iterations.
JMH will instantiate these and collect results from all of them. More forks mean more accuracy but longer testing. Warmup - it’s a phase before testing to let JVM apply all just-in-time optimisations it has. Number of iterations means how many times your test will be run before actual, measured test. Number of iterations measured for the test.
JMH is a Java harness library for writing benchmarks on the JVM, and it was developed as part of the OpenJDK project. JMH provides a very solid foundation for writing and running benchmarks whose results are not erroneous due to unwanted virtual machine optimizations. We can use the Maven generate archetype to create a JMH project
measurementIterations
defines how many measured iterations you want to measure of the benchmark. I don't know which parameters you have specified but by default JMH runs the benchmark time-based (default I guess 1 second). This means the benchmark method is invoked in that time frame as often as possible. There are possibilities to specify how often the method should be called in one iteration (-> batching).
I would recommend to study the JMH Samples provided by JMH: http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/ They are a very good introduction into JMH and cover pitfalls you easily make within benchmarks.
The number of iteration depends on the various JMH modes I think you must be using Avgtime mode it will perform various iterations. /////////////////////////////////////////////////////////////////////////////////
Mode.Throughput: Calculate number of operations in a time unit.
Mode.AverageTime: Calculate an average running time.
Mode.SampleTime: Calculate how long does it take for a method to run
(including percentiles).
Mode.SingleShotTime: Just runs a method
once (useful for cold-testing mode).
////////////////////////////////////////////////////////////////////////////////
For example Use mode "Mode.SingleShotTime", it will perform iteration exactly the number of times you mentioned in the run(see below).
// Example runner class
public static void main(String[] args) throws RunnerException {
Options opt = new OptionsBuilder()
.include(JMHSample_01_HelloWorld.class.getSimpleName())
.warmupIterations(1)// number of times the warmup iteration should take place
.measurementIterations(1)//number of times the actual iteration should take place
.forks(1)
.shouldDoGC(true)
.build();
new Runner(opt).run();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With