DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • Alternative Structured Concurrency
  • Jakarta EE 12: Entering the Data Age of Enterprise Java
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Rethinking Java CRUDs With Event Sourcing and CQRS Patterns

Trending

  • What Nobody Tells You About Multimodal Data Pipelines for AI Training
  • Building an Image Classification Pipeline With Apache Camel and Deep Java Library (DJL)
  • How AI Is Transforming Software Engineering and How Developers Can Take Advantage
  • Java Backend Development in the Era of Kubernetes and Docker
  1. DZone
  2. Coding
  3. Java
  4. Measuring Performance of Your Methods Using JMH in Java

Measuring Performance of Your Methods Using JMH in Java

In this article, I will be referring method as a component in isolation and show you how to test your methods using JMH as per their performances.

By 
Vishwa Ratna user avatar
Vishwa Ratna
DZone Core CORE ·
Jan. 22, 20 · Analysis
Likes (8)
Comment
Save
Tweet
Share
12.4K Views

Join the DZone community and get the full member experience.

Join For Free

rulers

Measure Java performance!

From JDK-12 onwards, the JDK comes with JMH (Java Microbenchmark Harness), It is a toolkit that helps you implement Java microbenchmarks correctly. JMH is developed by the same people who implement the Java virtual machine (JVM) so they know the internals and how Java makes optimizations at run time.


You may also like: JMH: Benchmark REST APIs


Why JMH?

There are many optimizations that the JVM  or underlying hardware may apply to your component when the benchmark executes that component in isolation. These optimizations may not be possible to apply when the component is running as part of a larger application. Badly implemented microbenchmarks may thus make you believe that your component’s performance is better than it will be in reality.

Whenever we come across a problem, we tend to solve it recursively, iteratively or by using inbuilt methods provided in our language. After coding we tend to confuse that for a given set of data(large, small, Fixed) will I have a better edge to use inbuilt methods or method 1 or method 2 or...method 3.

In this article, I will be referring method as a component in isolation, As my whole agenda is to show you how to test your methods using JMH as per their performances.

Before starting there are few prerequisites, If you don’t have JDK 12 then you need to import the dependencies in your project for that you can either download the JARs of making a maven project and adding below dependencies:

Java
 




x
15


 
1
  <dependencies>
2
<dependency>
3
<artifactId>jmh-core</artifactId>
4
<groupId>org.openjdk.jmh</groupId>
5
<version>${jmh.version}</version>
6
</dependency>
7
<dependency>
8
<artifactId>jmh-generator-annprocess</artifactId>
9
<groupId>org.openjdk.jmh</groupId>
10
<version>${jmh.version}</version>
11
</dependency>
12
</dependencies>
13
<p>
14
<jmh.version>1.21</jmh.version>
15
  </properties>



For the sake of simplicity, let's take an example to generate N natural numbers and store them in a List.

  • A simple or traditional approach will be to use a loop which will execute from 1 to N and store each number to List<Integer> list by list.add() .
  • A more functional approach will be to use stream to generate a Intstream from 1 to N and then store than to list.
Java
 




xxxxxxxxxx
1
49


 
1
import java.util.ArrayList;
2
import java.util.List;
3
import java.util.stream.Collectors;
4
import java.util.stream.IntStream;
5
import org.openjdk.jmh.annotations.Benchmark;
6
import org.openjdk.jmh.annotations.BenchmarkMode;
7
import org.openjdk.jmh.annotations.Mode;
8
import org.openjdk.jmh.annotations.Param;
9
import org.openjdk.jmh.annotations.Scope;
10
import org.openjdk.jmh.annotations.State;
11
import org.openjdk.jmh.runner.Runner;
12
import org.openjdk.jmh.runner.RunnerException;
13
import org.openjdk.jmh.runner.options.Options;
14
import org.openjdk.jmh.runner.options.OptionsBuilder;
15
 
           
16
@State(Scope.Thread)
17
public class Testing {
18
 
           
19
  @Param({"10"})
20
  private int number;
21
 
           
22
  @Benchmark
23
  @BenchmarkMode({Mode.All})
24
  //traditional method to generate N numbers and store it in List
25
  public List<Integer> traditionalMethod(Testing T) {
26
    List<Integer> list = new ArrayList<>();
27
    for (int i = 1; i <= number; i++) {
28
      list.add(i);
29
    }
30
    return list;
31
  }
32
 
           
33
  @Benchmark
34
  @BenchmarkMode({Mode.All})
35
  //using #stream to generate N numbers and store it in List
36
  public List<Integer> streamMethod(Testing T) {
37
    return IntStream.rangeClosed(1, number).boxed().collect(Collectors.toList());
38
  }
39
 
           
40
  public static void main(String[] args) throws RunnerException {
41
    Options opt = new OptionsBuilder()
42
        .include(Testing.class.getSimpleName())
43
        .forks(1)
44
        .build();
45
 
           
46
    new Runner(opt).run();
47
  }
48
}
49
 
           



After running the program the results are as follows:

The throughput of the stream method is better for the small range of 10, it might or might not be the same for the larger data set.

The detailed project has been uploaded to GitHub, you can fork it and run in your own local environment and can do modify or add your own methods and check how they are working in terms of performance.

The following article used @BenchmarkMode({Mode.All}) which will benchmark all the following:

Throughput("thrpt", "Throughput, ops/time"),
AverageTime("avgt", "Average time, time/op"),
SampleTime("sample", "Sampling time"),
SingleShotTime("ss", "Single shot invocation time"),
 All("all", "All benchmark modes");

In case you need the only Throughput to be measured then use Mode.Throughput.

GitHub Link


Further Reading

How to Improve the Performance of a Java Application

Java (programming language)

Opinions expressed by DZone contributors are their own.

Related

  • Alternative Structured Concurrency
  • Jakarta EE 12: Entering the Data Age of Enterprise Java
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • Rethinking Java CRUDs With Event Sourcing and CQRS Patterns

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook