Java:使用JMH做Benchmark基准测试

avatar
作者
筋斗云
阅读量:3

BenchMark 又叫做基准测试,主要用来测试一些方法的性能,可以根据不同的参数以不同的单位进行计算(例如可以使用吞吐量为单位,也可以使用平均时间作为单位,在 BenchmarkMode 里面进行调整)。

依赖

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

使用示例

ArrayList 和 LinkedList 的遍历的性能差别

package com.demo;   import org.openjdk.jmh.annotations.*; import org.openjdk.jmh.runner.Runner; import org.openjdk.jmh.runner.RunnerException; import org.openjdk.jmh.runner.options.Options; import org.openjdk.jmh.runner.options.OptionsBuilder;  import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.concurrent.TimeUnit;   @BenchmarkMode(Mode.Throughput) // 吞吐量 @OutputTimeUnit(TimeUnit.MILLISECONDS) // 结果所使用的时间单位 @State(Scope.Thread) // 每个测试线程分配一个实例 @Fork(2) // Fork进行的数目 @Warmup(iterations = 4) // 先预热4轮 @Measurement(iterations = 10) // 进行10轮测试 public class BenchMarkDemo {      @Param({"10", "40", "70", "100"}) // 定义四个参数,之后会分别对这四个参数进行测试     private int n;      private List<Integer> array;     private List<Integer> list;      @Setup(Level.Trial) // 初始化方法,在全部Benchmark运行之前进行     public void init() {         array = new ArrayList<>(0);         list = new LinkedList<>();         for (int i = 0; i < n; i++) {             array.add(i);             list.add(i);         }     }      @Benchmark     public void arrayTraverse() {         for (int i = 0; i < n; i++) {             array.get(i);         }     }      @Benchmark     public void listTraverse() {         for (int i = 0; i < n; i++) {             list.get(i);         }     }      @TearDown(Level.Trial) // 结束方法,在全部Benchmark运行之后进行     public void arrayRemove() {         for (int i = 0; i < n; i++) {             array.remove(0);             list.remove(0);         }     }      public static void main(String[] args) throws RunnerException {         Options options = new OptionsBuilder().include(BenchMarkDemo.class.getSimpleName()).build();         new Runner(options).run();     } }  
# Run complete. Total time: 00:03:56  Benchmark                    (n)   Mode  Cnt       Score       Error   Units BenchMarkDemo.arrayTraverse   10  thrpt   20  337852.300 ± 10230.514  ops/ms BenchMarkDemo.arrayTraverse   40  thrpt   20  342619.598 ±  6272.177  ops/ms BenchMarkDemo.arrayTraverse   70  thrpt   20  342534.411 ±  6018.479  ops/ms BenchMarkDemo.arrayTraverse  100  thrpt   20  333470.068 ± 17285.845  ops/ms BenchMarkDemo.listTraverse    10  thrpt   20   45899.695 ±  2960.264  ops/ms BenchMarkDemo.listTraverse    40  thrpt   20    6615.649 ±   201.404  ops/ms BenchMarkDemo.listTraverse    70  thrpt   20    1910.175 ±    31.484  ops/ms BenchMarkDemo.listTraverse   100  thrpt   20     787.424 ±    25.747  ops/ms  

可以结合 Score 和 Unit 这两列,看到方法的效率。这里显然 arrayTraverse 的效率比 listTraverse 的高很多,因为 Unit 单位是 ops/ms,即单位时间内执行的操作数。所以显然在遍历的时候,ArrayList的效率是比LinkedList高的。

参考
使用JMH做Benchmark基准测试

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!