1. JMH简介
JMH 是 Java Microbenchmark Harness 的缩写。中文意思大致是 “JAVA 微基准测试套件”。可以理解为鲁大师给你电脑跑个分数测试下。
我习惯性把这个框架当做是jmeter性能测试框架的增强版,这个框架是专门针对java程序员开发代码时进行压力测试的一个框架。如果专业上来讲是软件测试开发专业使用的。但是作为java开发员来说,我们需要对我们的代码进行优化精益求精。写完代码后,自己可以用这个框架在自己idea开发软件上跑一遍测试一下。
官网如下:http://openjdk.java.net/projects/code-tools/jmh/
官方样例: http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/
2.创建JMH demo
2.1 创建maven项目
2.2 添加pom依赖
<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>mashibing.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>
2.3 idea安装JMH插件
file --> setting --> Plugins -->marketplace -->输入JMH 进行安装
安装后在如下图的installd 列表会出现JMH的插件
2.4 打开注解
compiler -> Annotation Processors -> Enable Annotation Processing
2.5 编写自己要进行测试的方法
测试下使用并行流进行计算相同一批数,是否比普通的单线程的快(虽然我们知道并行流会比较快,但是我们还是需要测试下得到最终结果)
public class JMHTestDemo {
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(JMHTestDemo::isPrime);
}
static boolean isPrime(int num) {
for(int i=2; i<=num/2; i++) {
if(num % i == 0) return false;
}
return true;
}
}
2.6 在test目录下编写我们的jmh测试代码
这里强调一下,一定要在test目录下进行编写
2.7 运行测试类,如果遇到下面的错误:
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
主要是需要系统环境变量中的TEMP变量
2.8JMH中的基本概念
1.Warmup 预热,由于JVM中对于特定代码会存在优化(本地化),预热对于测试结果很重要
2.Mesurement 总共执行多少次测试
3.Timeout
4.Threads 线程数,由fork指定
5.Benchmark mode 基准测试的模式 一般会选择Throughput 吞吐量进行测试
6.Benchmark 测试哪一段代码
2.9 测试结果
先测试单线程foreach的方法
public class AppTest
{
@Benchmark
@Warmup(iterations = 3, time = 1)
@Fork(5)
@BenchmarkMode(Mode.Throughput)
@Measurement(iterations = 3, time = 1)
public void testForEach() {
JMHTestDemo.foreach();
}
}
跑完后的的分数为8.716
再试下parallel 并行流进行计算结果
public class AppTest
{
@Benchmark
@Warmup(iterations = 3, time = 1)
@Fork(5)
@BenchmarkMode(Mode.Throughput)
@Measurement(iterations = 3, time = 1)
public void testForEach() {
JMHTestDemo.parallel();
}
}
随后计算的分数为49.271
从JMH压测的最后结果可以看出来parallel 并行流计算出来的score分数远大于foreach单线程的score分数。所以使用的parallel可以提高吞吐量。