JMH实战入门
引言
在多线程中有这样一个思想,就是尽可能的压榨cpu,这里就提到了效率。那么怎么知道一个程序的效率呢,JMH(java Microbenchmark Harness),就是专门测量方法性能好不好的一个工具。有时我们想测试自己写的代码的性能,就不用自己写测试代码,而可以直接用它了。本篇就对其做一个简单的介绍。
JMH使用步骤
这里会做一个小实验,测算不同方法的吞吐量,也是对JMH做一个简单的入门。
-
创建Maven项目,添加两个依赖:
1.1:jmh-core (jmh的核心)
1.2:jmh-generator-annprocess(注解处理包)
<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>
-
idea安装JMH插件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nfWXJ9r5-1651679078535)(C:\Users\27901\AppData\Roaming\Typora\typora-user-images\image-20220502123707707.png)]
-
由于用到了注解,打开运行程序注解配置
compiler -> Annotation Processors -> Enable Annotation Processing
-
定义需要测试类PS (ParallelStream)
在这个类中,并行处理流的一个程序,定义了一个list集合,然后往这个集合里扔了1000个数。写了一个方法来判断这个数到底是不是一个质数。写了两个方法,第一个是用forEach来判断我们这1000个数里到底有谁是质数;第二个是使用了并行处理流,这个forEach的方法就只有单线程里面执行,挨着从头拿到尾,从0拿到1000,但是并行处理的时候会有多个线程采用ForkJoin的方式来把里面的数分成好几份并行的尽兴处理。一种是串行处理,一种是并行处理,对这两个方法进行性能测试。
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; } }
-
写单元测试
这个测试类一定要在test package下面
我对这个方法进行测试testForEach,很简单我就调用PS这个类的foreach就行了,对它测试最关键的是我加了这个注解@Benchmark,这个是JMH的注解,是要被JMH来解析处理的,这也是我们为么要把那个Annotation Processing给设置上的原因,非常简单,你只要加上注解就可以对这个方法进行微基准测试了,点击右键直接run。
public class PSTest { @Benchmark @Fork(5)//意思是用多少个线程去执行我们的程序 @BenchmarkMode(Mode.Throughput)//是对基准测试的一个模式,这个模式用的最多的是Throughput吞吐量 @Measurement(iterations=1, time=3)//是整个测试要测试多少遍,调用这个方法要调用多少次 public void testForEach() { // PS.foreach(); PS.parallel(); } }
-
Run配置,运行访问环境变量。
RunConfiguration -> Environment Variables -> include system environment viables
-
测试结果
foreach方法,可以看到其每秒能执行0.768 ± 0.010次
Benchmark Mode Cnt Score Error Units PSTest.testForEach thrpt 25 0.768 ± 0.010 ops/s
parallel方法,可以看到其每秒能执行5.885 ± 1.483次
Benchmark Mode Cnt Score Error Units PSTest.testForEach thrpt 5 5.885 ± 1.483 ops/s
JMH中的基本概念
- Warmup
预热,由于JVM中对于特定代码会存在优化(本地化),预热对于测试结果很重要 - Mesurement
总共执行多少次测试 - Threads
线程数,由fork指定 - Benchmark mode
基准测试的模式 - Benchmark
测试哪一段代码
说在最后
本文是用JMH对一个方法的吞吐量进行了性能测试,作为JMH的入门例子。实际JMH还有很多用法,进一步探索可以去看官方的例子。文章来源:https://www.toymoban.com/news/detail-401901.html
官方样例:
http://hg.openjdk.java.net/code-tools/jmh/file/tip/jmh-samples/src/main/java/org/openjdk/jmh/samples/文章来源地址https://www.toymoban.com/news/detail-401901.html
到了这里,关于java准测试套件—JMH实战入门的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!