OpenJDK:JMH Simple Usage

Introduction

Few people have heard of JMH, yet if harnessed properly, can be a very valuable tool, typically when we come across performance considerations. Now and then we will come across a task that can be done multiple different ways but we are unsure which one is the best performing code. A quick JMH code over Java command line application can quickly tell you how is one code performing compared to the other.
What JMH does when properly coded is to take your piece of code and run it for multiple warm up iterations to clear the memory cache, and then run it again over X amount iterations to obtain the averaged benchmark result.

Elaboration

Using JMH

It is recommended to use JMH in the most simplest java way, ie using the old and standard public static void main:

public static void main(String[] args) throws RunnerException {
  Options opt = new OptionsBuilder()
      .include(JmhTestRun.class.getSimpleName())
      .forks(1)
      .build();
  new Runner(opt).run();}

Afterwards, we simply just need to create the Benchmark tests as simple as follow:
@Benchmark@BenchmarkMode(Mode.AverageTime)
public void benchmarkEqualIgnoreCase() {
  for(int i = 0; i < data.size(); i++) {
    if(data.get(i).equalsIgnoreCase("string500")) {
      break;    }
  }
}

Do note that since you want to test the function, in this example its the equalsIgnoreCase(), make sure that any data preparations is done outside the method or it will skew the benchmark result

Then just simply run the simple java class and JMH will start, it will iterate through to warm up before doing the actual benchmarking. After a while you will see the result:


As you can see, the result here is not clear, this is because we are benchmarking average time it takes to finish the operation, which is very very minute, therefore we should change it to Throughput and run it again, the result will be much clearer:


Finally we can conclude that the equal() is almost 7x faster than equalsIgnoreCase()

Using JMH on Spring Boot Application

It is possible to use JMH on a typical Spring Boot application, however due to the complex nature of Spring Boot application, in most cases, we will not get a clear benchmark result from it. I believe that JMH is not meant to be used to benchmark a Spring Boot application, or any complex client server based application, Gatling (https://gatling.io/) might be more suitable for such purpose.

Below is the result of running the same test above but in Spring Boot application:


As you can see there is no significant differences between equal ignore case and equal only executions in term of ops per second. This is simply due to Spring Boot background processes weighing way more heavily than a simple equal execution over 1000 samples.



Complete source code: https://github.com/overtakerx/jmhdemo



http://javadox.com/org.openjdk.jmh/jmh-core/0.9/org/openjdk/jmh/annotations/Mode.html
https://openjdk.java.net/projects/code-tools/jmh/

Comments

Popular posts from this blog

Spring Boot 2: Parallelism with Spring WebFlux

Cucumber + Junit5 + Localstack