【进阶之路】Java代码性能调优-基准测试工具JMH(三)

导言

大家好,我是南橘,从接触java到现在也有差不多两年时间了,两年时间,从一名连java有几种数据结构都不懂超级小白,到现在懂了一点点的进阶小白,学到了不少的东西。知识越分享越值钱,我这段时间总结(包括从别的大佬那边学习,引用)了一些平常学习和面试中的重点(自我认为),希望给大家带来一些帮助

第一件事还是把思维导图贴给大家,因为用的是免费版,所以有水印,如果需要原始版本的话,可以加我的微信:

【进阶之路】Java代码性能调优-基准测试工具JMH(三)_第1张图片

【进阶之路】Java代码性能调优(一)

【进阶之路】Java代码性能调优(二)

前两章介绍了JAVA代码调优的一些方法,这一章我们就一起学习一下代码调优时的测试工具JMH

一、JMH介绍

JMH(Java Microbenchmark Harness)是用于代码微基准测试的工具套件,主要是基于方法层面的基准测试,精度可以达到纳秒级。

基准测试是指通过设计科学的测试方法、测试工具和测试系统,实现对一类测试对象的某项性能指标进行定量的和可对比的测试。

应用场景

  • 想准确地知道某个方法需要执行多长时间,以及执行时间和输入之间的相关性
  • 对比接口不同实现在给定条件下的吞吐量
  • 查看多少百分比的请求在多长时间内完成

具体内容可以查看JMH的官方DEMO
JMH官方DEMO

二、JMH使用注解总结

1、BenchmarkMode

JMH测试时运行的模式模式

类型 效用
Mode.All 所有模式依次运行(测试时使用最多)
Mode.Throughput 每段时间执行的次数,一般是秒
Mode.AverageTime 平均时间,每次操作的平均耗时
Mode.SampleTime 在测试中,随机进行采样执行的时间
Mode.SingleShotTime 在每次执行中计算耗时

可以组合使用

2、OutputTimeUnit

用来决定JMH测试的指定时间单位,它需要一个标准Java类型java.util.concurrent.TimeUnit作为参数。

3、Warmup

进行基准测试前需要进行预热。

在进行微基准测试时,我们想要测试的是“程序被JVM编译成机器代码(而不是直接执行字节码)”的执行速度。为了让JVM把要测试的代码编译成机器码,我们可能需要把要测试的代码进行“预热处理”(就是先跑几回,或十几回等,当运行的次多了,JVM就会生成机器码),JMH就提供“预热处理”等一系列的处理。

4、State

注解定义了给定类实例的可用范围

【进阶之路】Java代码性能调优-基准测试工具JMH(三)_第2张图片

5、Measurement

给定基本的测试参数。

  • iterations进行测试的轮次
  • time每轮进行的时长
  • timeUnit时长单位

6、Fork

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

7、Threads

该测试使用的线程数。默认是Runtime.getRuntime().availableProcessors()

8、Benchmark

方法注解,表示该方法是需要进行 benchmark 的对象。

9、Setup

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

10、TearDown

与@Setup 相对的,会在所有 benchmark 执行结束以后执行,主要用于资源的回收等。

11、Param

成员注解,可以用来指定某项参数的多种情况。特别适合用来测试一个函数在不同的参数输入的情况下的性能。@Param注解接收一个String数组,在@setup方法执行前转化为为对应的数据类型。多个@Param注解的成员之间是乘积关系,譬如有两个用@Param注解的字段,第一个有5个值,第二个字段有2个值,那么每个测试方法会跑5*2=10次。

三、JMH使用

1、添加依赖

因为 JMH 是 JDK9 自带的,如果是 JDK9 之前的版本需要加入依赖(人人都用JAVA8)

    
        org.openjdk.jmh
        jmh-core
        ()
    
    
        org.openjdk.jmh
        jmh-generator-annprocess
        
    

2、代码演示

先找到之前做过测试的代码




public class CommonUtils {
    static int cacheSize =1024;
    static String[] caches =new String[cacheSize];
    static {
        for(int i=0;i

点击运行得出结论

【进阶之路】Java代码性能调优-基准测试工具JMH(三)_第3张图片

  • 1、我们可以分别看到 两个方法依次对Param里的参数进行了测试。
  • 2、Mode里的参数thrpt是Throughput的简写
  • 3、Cnt表示测试了三遍
  • 4、Score通过对Mode的参数的解读,得出每毫秒执行的次数(ops/ms)
  • 5、Error表示测试的误差,测试轮次越多误差越小(大概吧)

四、JMH 插件

大家还可以通过 IDEA 安装 JMH 插件使 JMH 更容易实现基准测试,在 IDEA 中点击 File->Settings…->Plugins,然后搜索 jmh,选择安装 JMH plugin:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HpZwV7Mx-1592827698284)(https://user-gold-cdn.xitu.io/2020/6/22/172dbe689d32b26d?w=1666&h=892&f=png&s=124377)]
这个插件可以让我们能够以 JUnit 相同的方式使用 JMH,主要功能如下:

  • 自动生成带有 @Benchmark 的方法像 JUnit 一样
  • 运行单独的 Benchmark 方法
  • 运行类中所有的 Benchmark 方法

比如可以通过右键点击 Generate.,选择操作 Generate JMH benchmark 就可以生成一个带有 @Benchmark 的方法。

还有将光标移动到方法声明并调用 Run 操作就运行一个单独的 Benchmark 方法。

将光标移到类名所在行,右键点击 Run 运行,该类下的所有被 @Benchmark 注解的方法都会被执行。

结语

我们在编写代码的过程中,稍稍一注意,就能全面提升代码的性能。本文主要介绍了性能基准测试工具 JMH,它可以通过一些功能来规避由 JVM 中的 JIT 或者其他优化对性能测试造成的影响。只需要将待测的业务逻辑用 @Benchmark 注解标识,就可以让 JMH 的注解处理器自动生成真正的性能测试代码,以及相应的性能测试配置文件。

同时需要思维导图的话,可以联系我,毕竟知识越分享越香!

你可能感兴趣的:(JAVA程序员进阶之路,java,编程语言,单元测试,后端,编辑器)