java benchmarks examples
In this post two examples of java benchmark:
- simple time example
- JMH
Simple time benchmark
If you need a rough idea for the elapsed time in seconds or milliseconds than you can use:
- System.nanoTime();
- System.currentTimeMillis()
In the program below we are getting 43th Fibonacci number by recursion. We are measuring the start and the end time. After that we are outputting time in several different formats: nanoseconds, milliseconds, seconds, minutes. Depending on your need you can get decimal precision for the seconds by division instead of using TimeUnit method. In this example you can see also how to convert nanoseconds to other units by method:
double seconds = TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS);
The simple code execution measurement in seconds:
package benchmark;
import java.util.concurrent.TimeUnit;
public class Simple {
public static void main(String[] args) {
int n = 43;
System.out.println("Fibonacci iteration:");
//
// Start , action and end
//
long start = System.nanoTime();
int fibN = fib(n);
System.out.printf("result = %d is: %d \n", n, fibN);
long elapsedTime = System.nanoTime() - start;
//
// Output in different formats: ms, ns, seconds, minutes
//
double seconds = TimeUnit.SECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS);
double secondDecimalPrecision = (double)elapsedTime / 1000000000.0;
double ms = TimeUnit.MILLISECONDS.convert(elapsedTime, TimeUnit.NANOSECONDS);
double minutes = TimeUnit.MINUTES.convert(elapsedTime, TimeUnit.NANOSECONDS);
System.out.printf("Nanoseconds: %d ms\n", elapsedTime );
System.out.printf("Miliseconds: %f ms\n", ms );
System.out.printf("Seconds: %f ms\n", seconds);
System.out.printf("Seconds2: %f ms\n", secondDecimalPrecision);
System.out.printf("MInutes: %f ms\n", minutes);
}
static int fib(int n) {
if (n<2) return 1;
else return fib(n-1) + fib(n-2);
}
}
result:
result = 43 is: 701408733
Nanoseconds: 2697330235 ms
Miliseconds: 2697.000000 ms
Seconds: 2.000000 ms
Seconds2: 2.697330 ms
MInutes: 0.000000 ms
Java Microbenchmark Harness example
For better, more precise and complete examples you can use JMH (Java Microbenchmark Harness). This one is more accurate but also more complicated to be done. You will need additional maven libraries to be added to your project.
Import required dependencies
Open your pom.xml file and add this dependencies inside (version 1.20 is the last one available at the time of writing the article. For more recent you can check: JMH Core )
<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-core</artifactId>
<version>1.20</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-generator-annprocess -->
<dependency>
<groupId>org.openjdk.jmh</groupId>
<artifactId>jmh-generator-annprocess</artifactId>
<version>1.20</version>
<scope>provided</scope>
</dependency>
Java classes and methods
Now adding the Java code - the code is searching for 52-th number from the Fibonacci sequence by recursion. Two classes are needed one to run the benchmark and the one that will be test. The Fibonacci code is in the second one:
- class BenchmarkRunner - used to run the benchmark
package benchmark;
public class BenchmarkRunner {
public static void main(String[] args) throws Exception {
org.openjdk.jmh.Main.main(args);
}
}
- class TestBM - the class that will be benchmarked. So here as you can see we have the code and the benchmark option.
package benchmark;
import org.openjdk.jmh.annotations.*;
public class TestBM {
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 1)
@Warmup(iterations = 2)
@Measurement(iterations = 1)
public void init() {
fib(52);
//fibbonaci(300);
}
static int fib(int n) {
if (n<2) return 1;
else return fib(n-1) + fib(n-2);
}
double fibbonaci(int n){
double prev=0d, next=1d, result=0d;
for (int i = 0; i < n; i++) {
result=prev+next;
prev=next;
next=result;
}
return result;
}
}
result:
# Run progress: 0.00% complete, ETA 00:00:03
# Fork: 1 of 1
# Warmup Iteration 1: 185.060 s/op
# Warmup Iteration 2: 184.308 s/op
Iteration 1: 185.068 s/op
Result "benchmark.TestBM.init":
185.068 s/op
# Run complete. Total time: 00:09:15
Benchmark Mode Cnt Score Error Units
TestBM.init avgt 185.068 s/op
You can play with the Fibonacci number - for 52 we get 185 seconds for recursive execution.
Settings
You can customize JMH in many ways. Here we are using simple configuration to measure the average time. The number of iterations for warm-up and measurement are set to 2 and 1. By default they are higher - 10 and 20.
Configuration:
@Benchmark
@BenchmarkMode(Mode.AverageTime)
@Fork(value = 1)
@Warmup(iterations = 2)
@Measurement(iterations = 1)
More information
Note: if you use JMH with intellij you can have a look on this plugin:
idea-jmh-plugin
If you use it without plugin in maven project you may need to clean your project - maven clean. Otherwise you can have unexpected results based on old executions.