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