@Threads(Threads.MAX)
 public class LinkedListIterationBenchMark {
  private static final int SIZE = 10000;private List list = new LinkedList<>();
     
     @Setup
     public void setUp() {
         for (int i = 0; i < SIZE; i++) {
             list.add(String.valueOf(i));
         }
     }@Benchmark
     @BenchmarkMode(Mode.Throughput)
     public void forIndexIterate() {
         for (int i = 0; i < list.size(); i++) {
             list.get(i);
             System.out.print(“”);
         }
     }@Benchmark
     @BenchmarkMode(Mode.Throughput)
     public void forEachIterate() {
         for (String s : list) {
             System.out.print(“”);
         }
     }
 }#### 3. 执行测试


运行 **JMH** 基准测试有两种方式,一个是生产jar文件运行,另一个是直接写main函数或者放在单元测试中执行。


生成jar文件的形式主要是针对一些比较大的测试,可能对机器性能或者真实环境模拟有一些需求,需要将测试方法写好了放在linux环境执行。具体命令如下$ mvn clean install
 $ java -jar target/benchmarks.jar我们日常中遇到的一般是一些小测试,比如我上面写的例子,直接在IDE中跑就好了。启动方式如下:public static void main(String[] args) throws RunnerException {
         Options opt = new OptionsBuilder()
                 .include(LinkedListIterationBenchMark.class.getSimpleName())
                 .forks(1)
                 .warmupIterations(2)
                 .measurementIterations(2)
              .output(“E:/Benchmark.log”)
                 .build();new Runner(opt).run();
     }#### 4. 报告结果


输出结果如下,


最后的结果:Benchmark                                      Mode  Cnt     Score   Error  Units
 LinkedListIterationBenchMark.forEachIterate   thrpt    2  1192.380          ops/s
 LinkedListIterationBenchMark.forIndexIterate  thrpt    2   206.866          ops/s整个过程:# Detecting actual CPU count: 12 detected
 # JMH version: 1.21
 # VM version: JDK 1.8.0_131, Java HotSpot™ 64-Bit Server VM, 25.131-b11
 # VM invoker: C:\Program Files\Java\jdk1.8.0_131\jre\bin\java.exe
 # VM options: -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.2\lib\idea_rt.jar=65175:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.2\bin -Dfile.encoding=UTF-8
 # Warmup: 2 iterations, 10 s each
 # Measurement: 2 iterations, 10 s each
 # Timeout: 10 min per iteration
 # Threads: 12 threads, will synchronize iterations
 # Benchmark mode: Throughput, ops/time
 # Benchmark: org.sample.jmh.LinkedListIterationBenchMark.forEachIterate# Run progress: 0.00% complete, ETA 00:01:20
 # Fork: 1 of 1
 # Warmup Iteration   1: 1189.267 ops/s
 # Warmup Iteration   2: 1197.321 ops/s
 Iteration   1: 1193.062 ops/s
 Iteration   2: 1191.698 ops/sResult “org.sample.jmh.LinkedListIterationBenchMark.forEachIterate”:
   1192.380 ops/s# JMH version: 1.21
 # VM version: JDK 1.8.0_131, Java HotSpot™ 64-Bit Server VM, 25.131-b11
 # VM invoker: C:\Program Files\Java\jdk1.8.0_131\jre\bin\java.exe
 # VM options: -javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.2\lib\idea_rt.jar=65175:D:\Program Files\JetBrains\IntelliJ IDEA 2018.2.2\bin -Dfile.encoding=UTF-8
 # Warmup: 2 iterations, 10 s each
 # Measurement: 2 iterations, 10 s each
 # Timeout: 10 min per iteration
 # Threads: 12 threads, will synchronize iterations
 # Benchmark mode: Throughput, ops/time
 # Benchmark: org.sample.jmh.LinkedListIterationBenchMark.forIndexIterate# Run progress: 50.00% complete, ETA 00:00:40
 # Fork: 1 of 1
 # Warmup Iteration   1: 205.676 ops/s
 # Warmup Iteration   2: 206.512 ops/s
 Iteration   1: 206.542 ops/s
 Iteration   2: 207.189 ops/sResult “org.sample.jmh.LinkedListIterationBenchMark.forIndexIterate”:
   206.866 ops/s# Run complete. Total time: 00:01:21
REMEMBER: The numbers below are just data. To gain reusable insights, you need to follow up on
 why the numbers are the way they are. Use profilers (see -prof, -lprof), design factorial
 experiments, perform baseline and negative tests that provide experimental control, make sure
 the benchmarking environment is safe on JVM/OS/HW level, ask for reviews from the domain experts.
 Do not assume the numbers tell you what you want them to tell.Benchmark                                      Mode  Cnt     Score   Error  Units
 LinkedListIterationBenchMark.forEachIterate   thrpt    2  1192.380          ops/s
 LinkedListIterationBenchMark.forIndexIterate  thrpt    2   206.866          ops/s### 注解介绍


下面我们来详细介绍一下相关的注解,


#### @BenchmarkMode


微基准测试类型。**JMH** 提供了以下几种类型进行支持:




| 类型 | 描述 |
| --- | --- |
| Throughput | 每段时间执行的次数,一般是秒 |
| AverageTime | 平均时间,每次操作的平均耗时 |
| SampleTime | 在测试中,随机进行采样执行的时间 |
| SingleShotTime | 在每次执行中计算耗时 |
| All | 所有模式 |


可以注释在方法级别,也可以注释在类级别,@BenchmarkMode(Mode.All)
 public class LinkedListIterationBenchMark {
  …
 }
 @Benchmark
 @BenchmarkMode({Mode.Throughput, Mode.SingleShotTime})
 public void m() {
  …
 }#### @Warmup


这个单词的意思就是预热,`iterations = 3`就是指预热轮数。@Benchmark
 @BenchmarkMode({Mode.Throughput, Mode.SingleShotTime})
 @Warmup(iterations = 3)
 public void m() {
  …
 }#### @Measurement


正式度量计算的轮数。


* `iterations` 进行测试的轮次
* `time` 每轮进行的时长
* `timeUnit`时长单位@Benchmark
 @BenchmarkMode({Mode.Throughput, Mode.SingleShotTime})
 @Measurement(iterations = 3)
 public void m() {
  …
 }#### @Threads


每个进程中的测试线程。@Threads(Threads.MAX)
 public class LinkedListIterationBenchMark {
  …
 }#### @Fork


进行 fork 的次数。如果 fork 数是3的话,则 JMH 会 fork 出3个进程来进行测试。@Benchmark
 @BenchmarkMode({Mode.Throughput, Mode.SingleShotTime})
 @Fork(value = 3)
 public void m() {
  …
 }#### @OutputTimeUnit


基准测试结果的时间类型。一般选择秒、毫秒、微秒。@OutputTimeUnit(TimeUnit.SECONDS)
 public class LinkedListIterationBenchMark {
  …
 }
#### @Benchmark


方法级注解,表示该方法是需要进行 benchmark 的对象,用法和 JUnit 的 `@Test` 类似。


#### @Param


属性级注解,`@Param` 可以用来指定某项参数的多种情况。特别适合用来测试一个函数在不同的参数输入的情况下的性能。


#### @Setup


方法级注解,这个注解的作用就是我们需要在测试之前进行一些**准备工作**,比如对一些数据的初始化之类的。


#### @TearDown


方法级注解,这个注解的作用就是我们需要在测试之后进行一些**结束工作**,比如关闭线程池,数据库连接等的,主要用于资源的回收等。