JMH

java微基准测试JMH引入报错RuntimeException: ERROR: Unable to find the resource: /META-INF/BenchmarkList

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

这里一定我注意,我解决的办法是上面的标红的scope 标签是provided 之前我填写的test一直报错!

provided,compile 都是可以的,但是这个包我们在生产中并不需要,一般写provided

scope为test表示依赖项目仅仅参与测试相关的工作,包括测试代码的编译,执行
2、eclipse上还报上述错误

eclipse需要安装apt插件,从eclipse marketplace上搜索apt,找到m2e-apt x.x.x 安装它。

maven启用apt

 

二、IDEA

2.1、idea安装JMH插件JMH plugin

File->Settings->Plugins->JMH plugin

 

 2.2、打开运行程序注解配置

因为JMH在运行的时候他用到了注解,注解这个东西你自己得写一个程序得解释他,所以你要把这个给设置上允许JMH能够对注解进行处理:
Compiler -> Annotation Processors -> Enable Annotation Processing(打钩)

 

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

ERROR: org.openjdk.jmh.runner.RunnerException: ERROR: Exception while trying to acquire the 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目录,解决办法是:
打开Run Configuration -> Environment Variables -> include system environment viables(勾选)

 

2.4、开始第一个简单的JMH程序

1、直接通过maven的命令,通过maven archetype生成jmh项目

2、然后在项目中编写需要进行微测的方法(可以指定检测输出,循环几次,以及测试数据)

3、maven clean install 打包,然后运行benchmark.jar

第一步:生成JMH项目

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DarchetypeVersion=1.25 -DgroupId=com.dxz -DartifactId=benchmark-demo -Dversion=1.0

 

执行完成后,在window资源管理器可以看到benchmark-demo项目生成好了:

 

第二步,在项目中编写自己需要测试的类

使用maven提供的默认类作为参考编写,先不用纠结注解的具体使用

package com.dxz;

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

public class Jmh {

    static List<Integer> nums = new ArrayList<>();

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

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

    static void parallel() {
        nums.parallelStream().forEach(Jmh::isPrime);
    }

    static boolean isPrime(int num) {
        for (int i = 2; i <= num / 2; i++) {
            if (num % i == 0) return false;
        }
        return true;
    }
}

package com.dxz;

import org.openjdk.jmh.annotations.*;

public class JmhTest {
    @Benchmark
    @Warmup(iterations = 1, time = 3)//在专业测试里面首先要进行预热,预热多少次,预热多少时间
    @Fork(5)//意思是用多少个线程去执行我们的程序
    @BenchmarkMode(Mode.Throughput)//是对基准测试的一个模式,这个模式用的最多的是Throughput吞吐量
    @Measurement(iterations = 1, time = 3)//是整个测试要测试多少遍,调用这个方法要调用多少次
    public void testForEach() {
        Jmh.foreach();
    }
}

 

第三步,运行

 

 结果:

C:\java\jdk1.8.0_111\bin\java.exe -Dfile.encoding=UTF-8 -classpath D:\study\jmh\benchmark-demo\target\classes;C:\Users\4cv748wpd3\.m2\repository\org\openjdk\jmh\jmh-core\1.25\jmh-core-1.25.jar;C:\Users\4cv748wpd3\.m2\repository\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;C:\Users\4cv748wpd3\.m2\repository\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar org.openjdk.jmh.Main com.dxz.JmhTest.testForEach
# JMH version: 1.25
# VM version: JDK 1.8.0_111, Java HotSpot(TM) 64-Bit Server VM, 25.111-b14
# VM invoker: C:\java\jdk1.8.0_111\jre\bin\java.exe
# VM options: -Dfile.encoding=UTF-8
# Warmup: 1 iterations, 3 s each
# Measurement: 1 iterations, 3 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.dxz.JmhTest.testForEach

# Run progress: 0.00% complete, ETA 00:00:30
# Fork: 1 of 5
# Warmup Iteration   1: 0.594 ops/s
Iteration   1: 0.646 ops/s

# Run progress: 20.00% complete, ETA 00:00:29
# Fork: 2 of 5
# Warmup Iteration   1: 0.626 ops/s
Iteration   1: 0.620 ops/s

# Run progress: 40.00% complete, ETA 00:00:21
# Fork: 3 of 5
# Warmup Iteration   1: 0.642 ops/s
Iteration   1: 0.639 ops/s

# Run progress: 60.00% complete, ETA 00:00:14
# Fork: 4 of 5
# Warmup Iteration   1: 0.628 ops/s
Iteration   1: 0.637 ops/s

# Run progress: 80.00% complete, ETA 00:00:07
# Fork: 5 of 5
# Warmup Iteration   1: 0.652 ops/s
Iteration   1: 0.647 ops/s


Result "com.dxz.JmhTest.testForEach":
  0.638 ±(99.9%) 0.041 ops/s [Average]
  (min, avg, max) = (0.620, 0.638, 0.647), stdev = 0.011
  CI (99.9%): [0.597, 0.679] (assumes normal distribution)


# Run complete. Total time: 00:00:34

REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
experiments, perform baseline and negative tests that provide experimental control, make sure
the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
Do not assume the numbers tell you what you want them to tell.

Benchmark             Mode  Cnt  Score   Error  Units
JmhTest.testForEach  thrpt    5  0.638 ± 0.041  ops/s

Process finished with exit code 0

 

 

 

 

参考:

https://blog.csdn.net/mwqyykl/article/details/109367115

https://blog.csdn.net/qq_24101357/article/details/106000626

posted on 2019-01-09 23:30  duanxz  阅读(5191)  评论(0编辑  收藏  举报