JMH(Java Microbenchmark Harness) Java微基准测试

官网:OpenJDK: jmh

什么是JMH?微基准测试,他是测的某一个方法的性能到底是好或者不好,换了方法的实现之后他的性能到底好还是不好

创建JMH测试

  1. 创建Maven项目,添加依赖,我们需要添加两个依赖:

    1.1:jmh-core (jmh的核心)

    1.2:jmh-generator-annprocess(注解处理包)

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <encoding>UTF-8</encoding>
            <java.version>1.8</java.version>
            <maven.compiler.source>1.8</maven.compiler.source>
            <maven.compiler.target>1.8</maven.compiler.target>
        </properties>
    
        <groupId>xw.com</groupId>
        <artifactId>HelloJMH2</artifactId>
        <version>1.0-SNAPSHOT</version>
    
    
        <dependencies>
            <!-- 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>
        </dependencies>
    
    
    </project>
  2. idea安装JMH插件 JMH plugin v1.0.3

    JMH这个东西你要想真正的安安静静的去运行,就不会去影响我们正常程序的执行,最好的方式就是按照官网的说法是命令行的方式,比方说你要测试某一个包里面的类的话你应该把这个类和其他的依赖类打成一个jar包,然后单独的把这个jar包放到某一个机器上,在这个机器上对这个jar包进行微基准的测试,如果对他进行测试的比较好,那说明最后的结果还可以,如果说边开发边进行这种微基准的测试实际上他非常的不准,因为你的开发环境会对结果产生影响。只不过我们自己开发人员来说平时你要想进行一些微基准的测试的话,你要是每次打个包来进行正规一个从头到尾的测试 ,完了之后发现问题不对再去重新改,效率太低了。所以在这里教大家的是怎么样在IDE里面来进行微基准的测试。idea安装JMH插件:file->Settings->Plugins->JMH-plugin。它运行的时候需要这个plugin的支持,如果你用命令行是不需要这些东西的。

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

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

  4. 定义需要测试类PS (ParallelStream)

    看这里,写了一个类,并行处理流的一个程序,定义了一个list集合,然后往这个集合里扔了1000个数。写了一个方法来判断这个数到底是不是一个质数。写了两个方法,第一个是用forEach来判断我们这1000个数里到底有谁是质数;第二个是使用了并行处理流,这个forEach的方法就只有单线程里面执行,挨着牌从头拿到尾,从0拿到1000,但是并行处理的时候会有多个线程采用ForkJoin的方式来把里面的数分成好几份并行的尽兴处理。一种是串行处理,一种是并行处理,都可以对他们进行测试,但需要注意这个基准测试并不是对比测试的,你只是侧试一下你这方法写出这样的情况下他的吞吐量到底是多少,这是一个非常专业的测试的工具。严格的来讲这部分是测试开发专业的。

    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. 写单元测试

    /**
     * 这个测试类一定要在test package下面
     * 我对这个方法进行测试testForEach,很简单我就调用PS这个类的foreach就行了,
     * 对它测试最关键的是我加了这个注解@Benchmark,这个是JMH的注解,是要被JMH来解析处理的,
     * 这也是我们为么要把那个Annotation Processing给设置上的原因,非常简单,
     * 你只要加上注解就可以对这个方法进行微基准测试了,点击右键直接run。
     */
    import org.openjdk.jmh.annotations.Benchmark;
    import static org.junit.jupiter.api.Assertions.*;
    public class PSTest {
        @Benchmark
        @Warmup(iteration=1, time=3)//在专业测试里面首先要进行预热,预热多少次,预热多少时间
        @Fork(5)//意思是用多少个线程去执行我们的程序
        @BenchmarkMode(Mode.Throughput)//是对基准测试的一个模式,这个模式用的最多的是Throughput吞吐量
        @Measurement(iteration=1, time=3)//是整个测试要测试多少遍,调用这个方法要调用多少次
        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. Mesurement 总共执行多少次测试

  3. Timeout

  4. Threads 线程数,由fork指定

  5. Benchmark mode 基准测试的模式

  6. Benchmark 测试哪一段代码

做个是JMH的一个入门,严格来讲这个和我们的关系其实并不大,这个是测试部门干的事儿,但是你了解一下没有特别多的坏处,你也知道你的方法最后效率高或者底,可以通过一个简单的JMH插件来帮你完成,你不要在手动的去写这件事儿了。

如果说大家对JMH有兴趣,可以自己一个一个的去研究。

官方样例: http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值