JMH的全称是Java Microbenchmark Harness,是一个open JDK中用来做性能测试的套件。该套件已经被包含在了JDK 12中。

本文将会讲解如何使用JMH来在java中做性能测试。

如果你使用的不是JDK 12,那么需要添加如下依赖:

org.openjdk.jmh

jmh-core

1.19

org.openjdk.jmh

jmh-generator-annprocess

1.19

使用JMH做性能测试

如果我们想测试某个方法的性能,一般来说就是重复执行某个方法n次,求出总的执行时间,然后求平均值。

但是这样通常会有一些问题,比如程序的头几次执行通常会比较慢,因为JVM会对多次执行的代码进行优化。另外得出的统计结果也不够直观,需要我们自行解析。

如果使用JMH可以轻松解决这些问题。

在JMH中,将要测试的方法添加@Benchmark注解即可:

@Benchmark

public void measureThroughput() throws InterruptedException {

TimeUnit.MILLISECONDS.sleep(100);

}

看下怎么调用:

public static void main(String[] args) throws RunnerException {

Options opt = new OptionsBuilder()

.include(BenchMarkUsage.class.getSimpleName())

// .include(BenchMarkUsage.class.getSimpleName()+".*measureThroughput*")

// 预热3轮

.warmupIterations(3)

// 度量5轮

.measurementIterations(5)

.forks(1)

.build();

new Runner(opt).run();

}

上面的例子,我们通过OptionsBuilder的include方法添加了需要进行测试的类。

默认情况下,该类的所有@Benchmark方法都将会被测试,如果我们只想测试其中的某个方法,我们可以在类后面加上方法的名字:

.include(BenchMarkUsage.class.getSimpleName()+".*measureAll*")

上面的代码支持通配符。

warmupIterations(3)意思是在真正的执行前,先热身三次。

measurementIterations(5)表示我们将方法运行5次来测试性能。

forks(1)表示启动一个进程来执行这个任务。

上面是最基本的运行,我们看下运行结果:

# JMH version: 1.19

# VM version: JDK 1.8.0_171, VM 25.171-b11

# VM invoker: /Library/Java/JavaVirtualMachines/jdk1.8.0_171.jdk/Contents/Home/jre/bin/java

# VM options: -javaagent:/Applications/IntelliJ IDEA 2.app/Contents/lib/idea_rt.jar=55941:/Applications/IntelliJ IDEA 2.app/Contents/bin -Dfile.encoding=UTF-8

# Warmup: 3 iterations, 1 s each

# Measurement: 5 iterations, 1 s each

# Timeout: 10 min per iteration

# Threads: 1 thread, will synchronize iterations

# Benchmark mode: Throughput, ops/time

# Benchmark: com.flydean.BenchMarkUsage.measureThroughput

# Run progress: 26.66% complete, ETA 00:01:42

# Fork: 1 of 1

# Warmup Iteration 1: 9.727 ops/s

# Warmup Iteration 2: 9.684 ops/s

# Warmup Iteration 3: 9.678 ops/s

Iteration 1: 9.652 ops/s

Iteration 2: 9.678 ops/s

Iteration 3: 9.733 ops/s

Iteration 4: 9.651 ops/s

Iteration 5: 9.678 ops/s

Result "com.flydean.BenchMarkUsage.measureThroughput":

9.678 ±(99.9%) 0.129 ops/s [Average]

(min, avg, max) = (9.651, 9.678, 9.733), stdev = 0.034

CI (99.9%): [9.549, 9.808] (assumes normal distribution)

ops/s 是每秒的OPS次数。程序会给出运行的最小值,平均值和最大值。同时给出标准差stdev和置信区间CI。

BenchmarkMode

上面的例子中, 我们只用了最简单的@Benchmark。如果想实现更加复杂和自定义的BenchMark,我们可以使用@BenchmarkMode。

先举个例子:

@Benchmark

@BenchmarkMode(Mode.Throughput)

@OutputTimeUnit(TimeUnit.SECONDS)

public void measureThroughput() throws InterruptedException {

TimeUnit.MILLISECONDS.sleep(100);

}

上面的例子中,我们指定了@BenchmarkMode(Mode.Throughput),Throughput的意思是整体吞吐量,表示给定的时间内执行的次数。

这里我们通过 @OutputTimeUnit(TimeUnit.SECONDS)来指定时间单位。

Mode除了Throughput还有如下几种模式:

AverageTime - 调用的平均时间

SampleTime - 随机取样,最后输出取样结果的分布

SingleShotTime - 只会执行一次,通常用来测试冷启动时候的性能。

All - 所有的benchmark modes。

Fork和Warmup

上面的例子中我们通过代码来显式的制定Fork和Warmup,我们也可以使用注解来实现:

@Fork(value = 1, warmups = 2)

@Warmup(iterations = 5)

上面的例子中value表示该benchMark执行多少次,warmups表示fork多少个进程来执行。iterations表示warmup的iterations个数。

如果你同时在代码中和注解中都配置了相关的信息,那么注解将会覆盖掉代码中的显示配置。

State和Scope

如果我们在多线程环境中使用beachMark,那么多线程中用到的类变量是共享还是每个线程一个呢?

这个时候我们就要用到@State注解。

@State(Scope.Benchmark)

public class StateUsage {

}

Scope有三种:

Scope.Thread:默认的State,每个测试线程分配一个实例;

Scope.Benchmark:所有测试线程共享一个实例,用于测试有状态实例在多线程共享下的性能;

Scope.Group:每个线程组共享一个实例;

benchmark java_在java中使用JMH(Java Microbenchmark Harness)做性能测试相关推荐

  1. 在java中使用JMH(Java Microbenchmark Harness)做性能测试

    文章目录 使用JMH做性能测试 BenchmarkMode Fork和Warmup State和Scope 在java中使用JMH(Java Microbenchmark Harness)做性能测试 ...

  2. java中 数组声明,java数组声明格式

    java 声明动态数组,java对象数组详解,java中声明数组,java数组声明格式 Java 中数组的声明一维数组的声明: 在 Java 中,数组是独立的对象,有自身的方法,不是变量的集合. 数组 ...

  3. java中strictfp关键字,java strictfp关键字用法大全详解

    一.strictfp关键字简介 strictfp是Java中提供的一个保留关键字,该关键字是从这第java JDK2版本儿开始出现的一直沿用到现在,只不过很多情况下都不怎么使用,所以容易被大家遗忘,因 ...

  4. Java中的记录器 - Java日志示例

    Java中的记录器 - Java日志示例 今天我们将研究Java中的Logger.Java Logger提供了java编程的日志记录. 目录[ 隐藏 ] 1 Java中的记录器 1.1 Java Lo ...

  5. Java中的正则表达式 - Java Regex示例

    Java中的正则表达式 - Java Regex示例 欢迎使用Java中的正则表达式.它在Java中也称为Regex.当我开始编程时,java正则表达式对我来说是一场噩梦.本教程旨在帮助您掌握Java ...

  6. Java中apple导入那个包_在Java中,由Java编泽器自动导入而无需在程序中用import导入的包是()。A.java.appletB.java.awtC.j...

    在Java中,由Java编泽器自动导入而无需在程序中用import导入的包是().A.java.appletB.java.awtC.j 更多相关问题 问卷星是一个专业.无限制的免费在线问卷调查.测评. ...

  7. sonar java_修复Sonar中常见的Java安全代码冲突

    sonar java 本文旨在向您展示如何快速修复最常见的Java安全代码冲突. 它假定您熟悉代码规则和违规的概念以及Sonar如何对其进行报告. 但是,如果您以前从未听过这些术语,则可以阅读Sona ...

  8. 错误 eventqueue.java_线程“AWT-EventQueue-0”中的异常java.lang.NullPointerException [duplicate]...

    这个问题在这里已有答案: 我知道这个异常被问到的频率,我已经阅读了很多关于这个问题的线索,但我仍然不知道为什么这个错误总是出现,当我删除'mf'变量时,它确实有效,但没有显示图片起来 . 代码 . 名 ...

  9. java中properties作用,java中Properties类的使用

    java中Properties类的使用 在java.util 包下面有一个类 Properties,该类主要用于读取以项目的配置文件(以.properties结尾的文件和xml文件). Propert ...

最新文章

  1. 2022-2028年中国PET薄膜行业市场深度分析及未来趋势预测报告
  2. jquery实用应用之jquery操作radio、checkbox、select
  3. 浅谈大数据中的 2PC、3PC、Paxos、Raft、ZAB
  4. elasticsearch 常用命令
  5. ubuntu16.04安装ROS
  6. 方法重载,new,override
  7. 电话光端机的电话接口类型有哪些?
  8. 将list中的元素按照属性分类成树状的map
  9. Elasticsearch 数据写入原理
  10. 亚马逊开源模型设计神器:AutoGluon,三行代码自动生成SOTA模型!
  11. Chrome 错误代码:ERR_UNSAFE_PORT
  12. MySQL优化常见Extra分析——慢查询优化
  13. php 的cookie设置时间,php cookie时间设置的方法
  14. SFR算法详解(二)——斜棱法
  15. 施一公等团队登Science封面:AI与冷冻电镜揭示「原子级」NPC结构,生命科学突破...
  16. 2048游戏java教程_java版实现2048游戏功能
  17. 深度学习|费解的tensorflow
  18. 使用echarts制作地图+散点图的实例
  19. 如何在idea中配置SVN
  20. 小学教师资格证计算机知识,小学老师教师资格证复习内容是什么 小学教师资格证考试笔试必备知识点...

热门文章

  1. 从装机体验消费类软件市场
  2. c#开发地磅称重软件
  3. qt5 textedit怎么改变鼠标响应_聊聊鼠标的前世今生
  4. C++开源游戏推荐,雷神之锤1/2/3
  5. 视频转换为swf格式
  6. ubuntu下buffalo wzr-hp-300nh路由器刷DD-WRT系统
  7. 如何重定向cin和cout?
  8. W2k8应用vista主题
  9. [转]思科与华为之战:数据通信市场面临裂变
  10. 互联网构架技术全景图