JMH - Java微基准测试工具套件

这篇具有很好参考价值的文章主要介绍了JMH - Java微基准测试工具套件。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

JMH简介

    JMH 是 OpenJDK 团队开发的一款基准测试工具,一般用于代码的性能调优,精度甚至可以达到纳秒级别,适用于 java 以及其他基于 JVM 的语言。和 Apache JMeter 不同,JMH 测试的对象可以是任一方法,颗粒度更小,而不仅限于rest api

JMH 比较典型的应用场景如下:

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

JMH基础及常用注解说明

    JMH主要是通过注解的形式编写测试单元,告诉JMH如何测试,JMH自动生成测试代码,所以在使用JMH进行微基准测试时一定要先了对JMH注解有一定了解,下面就介绍下JMH的注解。

@Benchmark

    @Benchmark用于告诉JMH哪些方法需要进行测试,只能注解在方法上,有点类似junit@Test。在测试项目进行package时,JMH会针对注解了@Benchmark的方法生成Benchmark方法代码。通常情况下,每个Benchmark方法都运行在独立的进程中,互不干涉。

@BenchmarkMode

@BenchmarkMode用于指定当前Benchmark方法使用哪种模式测试。JMH提供了4种不同的模式,用于输出不同的结果指标,如下:

  1. Throughput:吞吐量,ops/time。单位时间内执行操作的平均次数
  2. AverageTime:每次操作所需时间,time/op。执行每次操作所需的平均时间
  3. SampleTime:同 AverageTime,区别在于 SampleTime会随机取样,最后输出取样结果的分布
  4. SingleShotTime:同 AverageTime。区别在于 SingleShotTime 只执行一次操作。这种模式的结果存在较大随机性。
  5. All:上边所有的都执行一遍

@BenchmarkMode支持数组,可以指定多种模式也可以配置All,所有模式都执行一遍

@Warmup和@Measurement

    @Warmup@Measurement分别用于配置预热迭代和测试迭代。其中,iterations用于指定迭代次数,timetimeUnit用于每个迭代的时间,batchSize表示执行多少次Benchmark方法为一个invocation

@State

    通过 State 可以指定一个对象的作用范围,JMH 根据 scope 来进行实例化和共享操作。@State 可以被继承使用,如果父类定义了该注解,子类则无需定义。由于 JMH 允许多线程同时执行测试,不同的选项含义如下:

  1. Scope.Benchmark:所有测试线程共享一个实例,测试有状态实例在多线程共享下的性能
  2. Scope.Group:同一个线程在同一个 group 里共享实例
  3. Scope.Thread:默认的 State,每个测试线程分配一个实例

@Setup 和 @TearDown

这两个注解只能定义在注解了 State 里,其中,@Setup类似于 junit 的@Before,而@TearDown类似于 junit 的@After。

@State(Scope.Thread)
public class JMHSample_05_StateFixtures {

    double x;

    @Setup(Level.Iteration)
    public void prepare() {
        System.err.println("init............");
        x = Math.PI;
    }

    @TearDown(Level.Iteration)
    public void check() {
        System.err.println("destroy............");
        assert x > Math.PI : "Nothing changed?";
    }

    @Benchmark
    public void measureRight() {
        x++;
    }
}

这两个注解注释的方法的调用时机,主要受Level的控制,JMH提供了三种Level,如下:

  1. Trial:Benchmark 开始前或结束后执行,如下。Level 为 Benchmark 的 Setup 和 TearDown 方法的开销不会计入到最终结果。
  2. Iteration:Benchmark 里每个 Iteration 开始前或结束后执行,如下。Level 为 Iteration 的 Setup 和 TearDown 方法的开销不会计入到最终结果。
  3. Invocation:Iteration 里每次方法调用开始前或结束后执行,如下。Level 为 Invocation 的 Setup 和 TearDown 方法的开销将计入到最终结果

@OutputTimeUnit

为统计结果的时间单位,可用于类或者方法注解

@Threads

每个进程中的测试线程,可用于类或者方法上。

@Fork

进行 fork 的次数,可用于类或者方法上。如果 fork 数是 2 的话,则 JMH 会 fork 出两个进程来进行测试。

JMH 陷阱

在使用 JMH 的过程中,一定要避免一些陷阱。

比如 JIT 优化中的死码消除,比如以下代码:

@Benchmark
public void testStringAdd(Blackhole blackhole) {
    String a = "";
    for (int i = 0; i < length; i++) {
        a += i;
    }
}

JVM 可能会认为变量 a 从来没有使用过,从而进行优化把整个方法内部代码移除掉,这就会影响测试结果。JMH 提供了两种方式避免这种问题,一种是将这个变量作为方法返回值 return a,一种是通过 Blackhole 的 consume 来避免 JIT 的优化消除。其他陷阱还有常量折叠与常量传播、永远不要在测试中写循环、使用 Fork 隔离多个测试方法、方法内联、伪共享与缓存行、分支预测、多线程测试等

IDEA插件

JMH plugin插件可以让我们像使用Junit一样使用JMH。

这个插件可以让我们能够以 JUnit 相同的方式使用 JMH,主要功能如下:自动生成带有 @Benchmark 的方法像 JUnit 一样,运行单独的 Benchmark 方法运行类中所有的 Benchmark 方法比如可以通过右键点击 Generate…,选择操作 Generate JMH benchmark 就可以生成一个带有 @Benchmark 的方法。还有将光标移动到方法声明并调用 Run 操作就运行一个单独的 Benchmark 方法。将光标移到类名所在行,右键点击 Run 运行,该类下的所有被 @Benchmark 注解的方法都会被执行。

集成使用

maven依赖和插件配置

        <!-- JMH的核心包 https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core -->
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-core</artifactId>
            <version>1.21</version>
        </dependency>

        <!-- JMH依赖注解,需要注解处理包 https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-generator-annprocess -->
        <dependency>
            <groupId>org.openjdk.jmh</groupId>
            <artifactId>jmh-generator-annprocess</artifactId>
            <version>1.21</version>
            <scope>test</scope>
        </dependency>

编写基准测试

@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3, time = 1)
@Measurement(iterations = 5, time = 5)
@Threads(4)
@Fork(1)
@State(value = Scope.Benchmark)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class StringConnectTest {

    @Param(value = {"10", "50", "100"})
    private int length;

    @Benchmark
    public void testStringAdd(Blackhole blackhole) {
        String a = "";
        for (int i = 0; i < length; i++) {
            a += i;
        }
        blackhole.consume(a);
    }

    @Benchmark
    public void testStringBuilderAdd(Blackhole blackhole) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append(i);
        }
        blackhole.consume(sb.toString());
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(StringConnectTest.class.getSimpleName())
                .result("result.json")
                .resultFormat(ResultFormatType.JSON).build();
        new Runner(opt).run();
    }
}

生成 jar 包执行

JMH 官方提供了生成 jar 包的方式来执行,我们需要在 maven 里增加一个 plugin,具体配置如下:

<plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-shade-plugin</artifactId>
        <version>2.4.1</version>
        <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>shade</goal>
                </goals>
                <configuration>
                    <finalName>jmh-demo</finalName>
                    <transformers>
                        <transformer
                                implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
                            <mainClass>org.openjdk.jmh.Main</mainClass>
                        </transformer>
                    </transformers>
                </configuration>
            </execution>
        </executions>
    </plugin>
</plugins>

运行基准测试文章来源地址https://www.toymoban.com/news/detail-409208.html

mvn clean install
java -jar target/jmh-demo.jar StringConnectTest

可视化

  • JMH Visual Chart:http://deepoove.com/jmh-visual-chart/
  • JMH Visualizer:https://jmh.morethan.io/

到了这里,关于JMH - Java微基准测试工具套件的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 【精通性能优化:解锁JMH微基准测试】一基本用法

    1. 什么是JMH JMH是Java Micro Benchmark Harness的简写,是专门用于代码微基准测试的工具集。 JMH由实现Java虚拟你的团队开发,现代JVM已经变的越来越智能,在Java文件的编译阶段、类的加载阶段,以及运行阶段都可能进行了不同程度的优化,因此开发者编写的代码未必会像自己所预

    2024年02月12日
    浏览(8)
  • 性能调优之JMH必知必会3:编写正确的微基准测试用例

      性能调优之JMH必知必会1:什么是JMH 性能调优之JMH必知必会2:JMH的基本用法 性能调优之JMH必知必会4:JMH的高级用法 性能调优之JMH必知必会5:JMH的Profiler       在前面两篇文章中分别介绍了什么是JMH、JMH的基本法。现在来介绍JMH正确的微基准测试用例如何编写。【 单位

    2023年04月08日
    浏览(11)
  • 22 从0到1:API测试怎么做?常用API测试工具简介

    准备测试数据(可选,不一定所有 API 测试都需要这一步); 通过 API 测试工具,发起对被测 API 的 request; 验证返回结果的 response。 发起 API 调用; 添加结果验证; 保存测试用例; 基于 Postman 的测试代码自动生成。         为了将测试 request 作为回归测试用例集成到 CI/

    2024年02月11日
    浏览(8)
  • 服务器能效测试工具BenchSEE使用方法简介

    服务器能效测试工具BenchSEE使用方法简介

    BenchSEE是由中国标准化研究院开发的一款针对 服务器产品能效 测试的基准软件。BenchSEE基准的设计参考了全球众多服务器厂家、芯片厂家、能效认证机构和IT节能领域科研机构的意见,旨在满足服务器市场应用对能效测评的需求。BenchSEE基准负载工具支持的服务器类型包括:机

    2024年03月16日
    浏览(184)
  • 自动化测试工具 AirTest 的使用方法与简介

    自动化测试工具 AirTest 的使用方法与简介

    目录         前言: Airtest简介 1.基于图像识别的Airtest框架 2.基于UI识别的Poco框架 Airtest环境搭建 Airtest布局 Airtest使用步骤 第一步:连接移动设备 第二步:创建一个.air文件(也就是我们的测试脚本) 第三步:用Airtest辅助窗口编辑第一个测试脚本 第四步:引入Poco Airtest常用

    2024年02月10日
    浏览(39)
  • 《渗透测试》-前期信息收集及工具介绍01(信息收集简介、JSFinder、OneForAll)

    《渗透测试》-前期信息收集及工具介绍01(信息收集简介、JSFinder、OneForAll)

    信息收集是指通过各种方式获取所需要的信息,以便我们在后续的渗透过程更好的进 行。比如目标站点IP、中间件、脚本语言、端口、邮箱等等。信息收集包含资产收集 但不限于资产收集。 1、信息收集是渗透测试成功的保障 2、更多的暴露面 3、更大的可能性 1、主动信息收

    2024年02月03日
    浏览(37)
  • 『App自动化测试之Appium应用篇』| 元素定位工具uiautomatorviewer从简介、特点、启动到使用的完整过程

    『App自动化测试之Appium应用篇』| 元素定位工具uiautomatorviewer从简介、特点、启动到使用的完整过程

    之前文章说明了 Appium Inspector 的定位使用方法; uiautomatorviewer 是另一种定位工具; uiautomatorviewer 是 android-sdk 自带的元素定位工具; 它是通过截屏分析 XML 布局文件方式,来提供控件信息的查看服务。 uiautomatorviewer 和 Appium Inspector 有着明显的区别; Appium Inspector 功能相对比较

    2024年02月03日
    浏览(25)
  • JAVA开发常用测试工具

    JAVA开发常用测试工具

    什么是junit JUnit 是一个用于编写和运行单元测试的开源框架,是Java 开发中最常用的单元测试框架之一。它为 Java 开发者提供了一种简单、灵活且可扩展的方式来编写自动化测试代码,并帮助开发者进行单元测试的管理和执行。 JUnit 提供了一组注解和断言方法,使开发者能够

    2024年04月25日
    浏览(13)
  • 性能测试工具 Jmeter 测试 JMS (Java Message Service)/ActiveMQ 性能

    目录 前言 ActiveMQ 介绍 准备工作 编写jndi.properties添加到ApacheJMeter.jar 中 下载 ActiveMQ 配置 Jmeter 进行测试 点对点 (Queues 队列)

    2024年02月15日
    浏览(39)
  • JMeter —— 3万字讲解让测试彻底臣服的基于 Java 之强大测试工具

    JMeter —— 3万字讲解让测试彻底臣服的基于 Java 之强大测试工具

    目录 一. 前言 二. JMeter 下载与安装 2.1. JMeter 下载 2.2. JMeter 安装 二. TestPlan 和线程组 三. JMeter 接口测试 四. JMeter 断言实现 4.1. 什么是断言 4.2. 断言的实现 4.2.1. 响应断言 4.2.2. JSON 断言 4.2.3. BeanShell 断言 4.2.4. 大小断言 4.2.5. 断言持续时间 五. JMeter BeanShell 断言 5.1. BeanS

    2024年01月22日
    浏览(7)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包