JMH JAVA基准测试框架

本文详细介绍了如何使用Java Microbenchmark Harness (JMH)进行基准测试,包括创建Maven项目、添加依赖、安装JMH插件、定义测试类、编写单元测试以及解决运行错误。JMH是OpenJDK提供的高性能基准测试工具,它允许开发者测量代码的性能,如吞吐量、平均执行时间等。预热和测量设置对于获取准确的测试结果至关重要。
摘要由CSDN通过智能技术生成

JMH简介
JMH即Java Microbenchmark Harness,是Java用来做基准测试的一个工具,该工具由OpenJDK提供并维护,测试结果可信度高。

基准测试Benchmark是测量、评估软件性能指标的一种测试,对某个特定目标场景的某项性能指标进行定量的和可对比的测试。

1. 创建maven 项目,添加依赖

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

        <!-- 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>

2.idea安装JMH插件 JMH plugin v1.0.3

3.由于用到了注解,打开运行程序注解配置

compiler -> Annotation Processors -> Enable Annotation Processing

4.定义需要测试类

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

public class PS {

	static List<Integer> nums = new ArrayList<>();
	static {
		Random r = new Random();
		for (int i = 0; i < 10000; i++) nums.add(1000000 + r.nextInt(1000000));
	}

	static void foreach() {
		nums.forEach(v->isPrime(v));
	}

	static void parallel() {
		nums.parallelStream().forEach(PS::isPrime);
	}
	
	static boolean isPrime(int num) {
		for(int i=2; i<=num/2; i++) {
			if(num % i == 0) return false;
		}
		return true;
	}
}

5.写单元测试 

import org.openjdk.jmh.annotations.Benchmark;

import static org.junit.jupiter.api.Assertions.*;

public class PSTest {

    @BenchmarkMode(Mode.AverageTime) // 指定mode为Mode.AverageTime
    @Benchmark
    @Fork(1)
    @Threads(2)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    @Warmup(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS)
    @Measurement(iterations = 5, time = 1, timeUnit = TimeUnit.SECONDS) //测试5次,每次测1秒钟
    public void testForEach() {
        PS.foreach();
    }
}

6.运行测试类,如果遇到下面的错误:

ERROR: org.openjdk.jmh.runner.RunnerException: ERROR: Exception while trying to acquire the JMH lock (C:\WINDOWS\/jmh.lock): C:\WINDOWS\jmh.lock (拒绝访问。), exiting. Use -Djmh.ignoreLock=true to forcefully continue.
	at org.openjdk.jmh.runner.Runner.run(Runner.java:216)
	at org.openjdk.jmh.Main.main(Main.java:71)

这个错误是因为JMH运行需要访问系统的TMP目录,解决办法是:

打开RunConfiguration -> Environment Variables -> include system environment viables

7.阅读测试报告

JMH中的基本概念

  1. Warmup 预热,由于JVM中对于特定代码会存在优化(本地化),预热对于测试结果很重要

  2. @Measurement 总共执行多少次测试   iterations:测量次数;time与timeUnit:每次测量的持续时间,timeUnit指定时间单位,本例中:每次测量持续1秒,1秒内执行的testForEach方法的次数是不固定的,由方法执行耗时和time决定。

  3. @OutputTimeUnit 用于指定输出的方法执行耗时的单位

  4. @Fork    用于指定fork出多少个子进程来执行同一基准测试方法。假设我们不需要多个进程,那么 可以使用@Fork指定为进程数为1

  5. @Threads 用于指定使用多少个线程来执行基准测试方法,如果使用@Threads指定线程数为2,那么每次测量都会创建两个线程来执行基准测试方法。

  6. @BenchmarkMode  基准测试的模式

    通过JMH我们可以轻松的测试出某个接口的吞吐量、平均执行时间等指标的数据。

    假设我想测试方法的平均耗时,那么可以使用@BenchmarkMode注解指定测试维度为Mode.AverageTime

  7. @Benchmark 测试哪一段代码

  8. @Warmup  预热,有三个配置项:iterations:预热次数;time与timeUnit:每次预热的持续时间,timeUnit指定时间单位。

官方样例: code-tools/jmh: 2be2df7dbaf8 /jmh-samples/src/main/java/org/openjdk/jmh/samples/



参考文章: https://blog.csdn.net/ZYC88888/article/details/113741316

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值