官网

http://openjdk.java.net/projects/code-tools/jmh/

创建JMH测试

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

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <project xmlns="http://maven.apache.org/POM/4.0.0"
    3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    4. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    5. <modelVersion>4.0.0</modelVersion>
    6. <properties>
    7. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    8. <encoding>UTF-8</encoding>
    9. <java.version>1.8</java.version>
    10. <maven.compiler.source>1.8</maven.compiler.source>
    11. <maven.compiler.target>1.8</maven.compiler.target>
    12. </properties>
    13. <groupId>mashibing.com</groupId>
    14. <artifactId>HelloJMH2</artifactId>
    15. <version>1.0-SNAPSHOT</version>
    16. <dependencies>
    17. <!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-core -->
    18. <dependency>
    19. <groupId>org.openjdk.jmh</groupId>
    20. <artifactId>jmh-core</artifactId>
    21. <version>1.21</version>
    22. </dependency>
    23. <!-- https://mvnrepository.com/artifact/org.openjdk.jmh/jmh-generator-annprocess -->
    24. <dependency>
    25. <groupId>org.openjdk.jmh</groupId>
    26. <artifactId>jmh-generator-annprocess</artifactId>
    27. <version>1.21</version>
    28. <scope>test</scope>
    29. </dependency>
    30. </dependencies>
    31. </project>
  2. idea安装JMH插件 JMH plugin v1.0.3

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

    compiler -> Annotation Processors -> Enable Annotation Processing

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

    package com.mashibing.jmh;
    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下面

package com.mashibing.jmh;
import org.openjdk.jmh.annotations.Benchmark;
import static org.junit.jupiter.api.Assertions.*;
public class PSTest {
    @Benchmark
    public void testForEach() {
        PS.foreach();
    }
}
  1. 运行测试类,如果遇到下面的错误:

    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)
    
  2. 这个错误是因为JMH运行需要访问系统的TMP目录,解决办法是:
    打开RunConfiguration -> Environment Variables -> include system environment viables

  3. 阅读测试报告

    JMH中的基本概念

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

  5. Mesurement 总共执行多少次测试
  6. Timeout
  7. Threads 线程数,由fork指定
  8. Benchmark mode 基准测试的模式
  9. Benchmark 测试哪一段代码

    Next

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