JMH性能测试——入门学习

一、简介

OpenJDK 中的开源项目 JMH(Java Microbenchmark Harness)。JMH 是一个面向 Java 语言或者其他 Java 虚拟机语言的性能基准测试框架。它针对的是纳秒级别、微秒级别、毫秒级别,以及秒级别的性能测试。

二、入门

1、maven依赖导入

<dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-core</artifactId>
      <version>1.19</version>
    </dependency>
    <dependency>
      <groupId>org.openjdk.jmh</groupId>
      <artifactId>jmh-generator-annprocess</artifactId>
      <version>1.19</version>
      <scope>provided</scope>
    </dependency>

2、例子

import java.io.UnsupportedEncodingException;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;
import org.joda.time.DateTime;
import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.Threads;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.Options;
import org.openjdk.jmh.runner.options.OptionsBuilder;
import org.openjdk.jmh.runner.options.TimeValue;

@OutputTimeUnit(TimeUnit.MILLISECONDS)
@BenchmarkMode(Mode.AverageTime)
@State(Scope.Benchmark)
public class JMHTest {

  static int millis = 24 * 3600 * 1000;

  public static void main(String[] args) throws Exception {
    Options options = new OptionsBuilder().include(JMHTest.class.getName()).warmupIterations(3)
        .measurementIterations(5).measurementTime(
            TimeValue.seconds(10)).forks(2).build();
    new Runner(options).run();
  }

  @Benchmark
  @Threads(5)
  public void runCalendar() {
    Calendar calendar = Calendar.getInstance();
  }

   @Benchmark
   @Threads(5)
  public void runJoda() {
    DateTime dateTime = new DateTime();
  }

  
  @Benchmark
  @Threads(5)
  public void runSystem() {
    long result = System.currentTimeMillis() / millis;
  }
}

3、运行方式

(1)运行JMHTest.main()方法

(2)在Terminal控制台输入mvn clean install(package),对项目进行打包;再输入java -jar ./target/benchmarks.jar运行

4、注解含义

(1)@BenchmarkMode  基准测试类型

*Mode.Throughput 整体吞吐量,例如“1秒内可以执行多少次调用”。
*Mode.AverageTime 调用的平均时间,例如“每次调用平均耗时xxx毫秒”
*Mode.SampleTime 随机取样,最后输出取样结果的分布,例如“99%的调用在xxx毫秒以内,99.99%的调用在xxx毫秒以内”
*Mode.SingleShotTime 以上模式都是默认一次 iteration 是 1s,唯有 SingleShotTime 是只运行一次。往往同时把 warmup 次数设为0,用于测试冷启动时的性能
*Mode.All 所有模式依次运行

*Iteration 是 JMH 进行测试的最小单位。在大部分模式下,一次 iteration 代表的是一秒,JMH 会在这一秒内不断调用需要 benchmark 的方法,然后根据模式对其采样,计算吞吐量,计算平均执行时间等。

(2)@Warmup
进行基准测试前需要进行预热。一般我们前几次进行程序测试的时候都会比较慢,所以要让程序进行几轮预热,保证测试的准确性。其中的参数iterations也就非常好理解了,就是预热轮数。

(3)@Fork

需要运行的试验(迭代集合)数量。每个试验运行在单独的JVM进程中。也可以指定(额外的)JVM参数。

(4)@OutputTimeUnit
benchmark 结果所使用的时间单位,可用于类或者方法注解,使用java.util.concurrent.TimeUnit中的标准时间单位。

(5)@Benchmark
方法注解,表示该方法是需要进行 benchmark 的对象。

(6)@Setup
方法注解,会在执行 benchmark 之前被执行,正如其名,主要用于初始化。

(7)@State
注解定义了给定类实例的可用范围。JMH可以在多线程同时运行的环境测试,因此需要选择正确的状态。当使用@Setup参数的时候,必须在类上加这个参数,不然会提示无法运行。

Scope.Thread 默认状态。实例将分配给运行给定测试的每个线程。
Scope.Benchmark 运行相同测试的所有线程将共享实例。可以用来测试状态对象的多线程性能(或者仅标记该范围的基准)。
Scope.Group 实例分配给每个线程组(查看后面的线程组部分)除了将单独的类标记@State,也可以将你自己的benchmark类使用
(8)@Threads

每个进程中的测试线程,可用于类或者方法上。一般选择为cpu乘以2。如果配置了 Threads.MAX ,代表使用 Runtime.getRuntime().availableProcessors() 个线程。

(9)@Measurement

度量,其实就是一些基本的测试参数。iterations进行测试的轮次,time每轮进行的时长,timeUnit时长单位。都是一些基本的参数,可以根据具体情况调整。一般比较重的东西可以进行大量的测试,放到服务器上运行。

5、测试结果

结果显示吞吐量Calendar方法每毫秒12768次调用;Joda每毫秒153347次调用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值