阅读量: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高的。