微基准测试JMH使用介绍

一.概述

JMH,即Java Microbenchmark Harness,是专门用于代码微基准测试的工具套件。何谓Micro Benchmark呢?简单的来说就是基于方法层面的基准测试,精度可以达到微秒级。当你定位到热点方法,希望进一步优化方法性能的时候,就可以使用JMH对优化的结果进行量化的分析。

JMH比较典型的应用场景有:

  • 想准确的知道某个方法需要执行多长时间,以及执行时间和输入之间的相关性;
  • 对比接口不同实现在给定条件下的吞吐量;
  • 查看多少百分比的请求在多长时间内完成; 

二.maven依赖

		<!--微基准测试 jmh-->
		<dependency>
			<groupId>org.openjdk.jmh</groupId>
			<artifactId>jmh-core</artifactId>
			<version>1.21</version>
		</dependency>
		<dependency>
			<groupId>org.openjdk.jmh</groupId>
			<artifactId>jmh-generator-annprocess</artifactId>
			<version>1.21</version>
			<scope>provided</scope>
		</dependency>

三.基本参数概念

@BenchmarkMode

Mode 表示 JMH 进行 Benchmark 时所使用的模式。通常是测量的维度不同,或是测量的方式不同。目前 JMH 共有四种模式:

  1. Throughput: 整体吞吐量,例如“1秒内可以执行多少次调用”,单位是操作数/时间。
  2. AverageTime: 调用的平均时间,例如“每次调用平均耗时xxx毫秒”,单位是时间/操作数。
  3. SampleTime: 随机取样,最后输出取样结果的分布,例如“99%的调用在xxx毫秒以内,99.99%的调用在xxx毫秒以内”
  4. SingleShotTime: 以上模式都是默认一次 iteration 是 1s,唯有 SingleShotTime 是只运行一次。往往同时把 warmup 次数设为0,用于测试冷启动时的性能。

@OutputTimeUnit

输出的时间单位。

@Iteration

Iteration 是 JMH 进行测试的最小单位。在大部分模式下,一次 iteration 代表的是一秒,JMH 会在这一秒内不断调用需要 Benchmark 的方法,然后根据模式对其采样,计算吞吐量,计算平均执行时间等。

@WarmUp

Warmup 是指在实际进行 Benchmark 前先进行预热的行为。

为什么需要预热?因为 JVM 的 JIT 机制的存在,如果某个函数被调用多次之后,JVM 会尝试将其编译成为机器码从而提高执行速度。为了让 Benchmark 的结果更加接近真实情况就需要进行预热。

@State

类注解,JMH测试类必须使用 @State 注解,它定义了一个类实例的生命周期,可以类比 Spring Bean 的 Scope。由于 JMH 允许多线程同时执行测试,不同的选项含义如下:

  1. Scope.Thread:默认的 State,每个测试线程分配一个实例;
  2. Scope.Benchmark:所有测试线程共享一个实例,用于测试有状态实例在多线程共享下的性能;
  3. Scope.Group:每个线程组共享一个实例;

@Fork

进行 fork 的次数。如果 fork 数是2的话,则 JMH 会 fork 出两个进程来进行测试。

@Meansurement

提供真正的测试阶段参数。指定迭代的次数,每次迭代的运行时间和每次迭代测试调用的数量(通常使用 @BenchmarkMode(Mode.SingleShotTime) 测试一组操作的开销——而不使用循环)

@Setup

方法注解,会在执行 benchmark 之前被执行,正如其名,主要用于初始化。

@TearDown

方法注解,与@Setup 相对的,会在所有 benchmark 执行结束以后执行,主要用于资源的回收等。

@Setup/@TearDown注解使用Level参数来指定何时调用fixture:

名称 描述  
Level.Trial 默认level。全部benchmark运行(一组迭代)之前/之后  
Level.Iteration 一次迭代之前/之后(一组调用)  
Level.Invocation 每个方法调用之前/之后(不推荐使用,除非你清楚这样做的目的)  

@Benchmark

方法注解,表示该方法是需要进行 benchmark 的对象。

@Param

成员注解,可以用来指定某项参数的多种情况。特别适合用来测试一个函数在不同的参数输入的情况下的性能。@Param 注解接收一个String数组,在 @Setup 方法执行前转化为为对应的数据类型。多个 @Param 注解的成员之间是乘积关系,譬如有两个用 @Param 注解的字段,第一个有5个值,第二个字段有2个值,那么每个测试方法会跑5*2=10次。

四.测试用例

package com.test;

import org.openjdk.jmh.annotations.Benchmark;
import org.openjdk.jmh.annotations.BenchmarkMode;
import org.openjdk.jmh.annotations.Fork;
import org.openjdk.jmh.annotations.Level;
import org.openjdk.jmh.annotations.Measurement;
import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.annotations.OutputTimeUnit;
import org.openjdk.jmh.annotations.Param;
import org.openjdk.jmh.annotations.Scope;
import org.openjdk.jmh.annotations.Setup;
import org.openjdk.jmh.annotations.State;
import org.openjdk.jmh.annotations.TearDown;
import org.openjdk.jmh.annotations.Warmup;
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;

/**
 *
 * @author zhaoj
 * @version BenchMark.java, v 0.1 2019-04-17 13:33
 */
@BenchmarkMode(Mode.Throughput) // 吞吐量
@OutputTimeUnit(TimeUnit.MILLISECONDS) // 结果所使用的时间单位
@State(Scope.Thread) // 每个测试线程分配一个实例
@Fork(2) // Fork进行的数目
@Warmup(iterations = 4) // 先预热4轮
@Measurement(iterations = 10) // 进行10轮测试
public class BenchMark {
    /**
     *  定义四个参数,之后会分别对这四个参数进行测试
     */
    @Param({"10", "40", "70", "100"})
    private int n;

    private List<Integer> array;
    private List<Integer> list;

    /**
     * 初始化方法,在全部Benchmark运行之前进行
     */
    @Setup(Level.Trial)
    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);
        }
    }

    /**
     * 结束方法,在全部Benchmark运行之后进行
     */
    @TearDown(Level.Trial)
    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(BenchMark.class.getSimpleName()).build();
        new Runner(options).run();
    }
}

五.测试报告

"C:\Program Files\Java\jdk1.8.0_102\bin\java" -Didea.launcher.port=7533 "-Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_102\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_102\jre\lib\rt.jar;D:\IdeaProjects\util-tool\target\classes;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter\2.1.3.RELEASE\spring-boot-starter-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot\2.1.3.RELEASE\spring-boot-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-autoconfigure\2.1.3.RELEASE\spring-boot-autoconfigure-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter-logging\2.1.3.RELEASE\spring-boot-starter-logging-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\ch\qos\logback\logback-classic\1.2.3\logback-classic-1.2.3.jar;C:\Users\WIN 10\.m2\repository\ch\qos\logback\logback-core\1.2.3\logback-core-1.2.3.jar;C:\Users\WIN 10\.m2\repository\org\apache\logging\log4j\log4j-to-slf4j\2.11.2\log4j-to-slf4j-2.11.2.jar;C:\Users\WIN 10\.m2\repository\org\apache\logging\log4j\log4j-api\2.11.2\log4j-api-2.11.2.jar;C:\Users\WIN 10\.m2\repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;C:\Users\WIN 10\.m2\repository\javax\annotation\javax.annotation-api\1.3.2\javax.annotation-api-1.3.2.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-core\5.1.5.RELEASE\spring-core-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-jcl\5.1.5.RELEASE\spring-jcl-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\yaml\snakeyaml\1.23\snakeyaml-1.23.jar;C:\Users\WIN 10\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;C:\Users\WIN 10\.m2\repository\org\apache\poi\poi\3.11\poi-3.11.jar;C:\Users\WIN 10\.m2\repository\commons-codec\commons-codec\1.11\commons-codec-1.11.jar;C:\Users\WIN 10\.m2\repository\org\apache\poi\poi-ooxml\3.11\poi-ooxml-3.11.jar;C:\Users\WIN 10\.m2\repository\org\apache\poi\poi-ooxml-schemas\3.11\poi-ooxml-schemas-3.11.jar;C:\Users\WIN 10\.m2\repository\org\apache\xmlbeans\xmlbeans\2.6.0\xmlbeans-2.6.0.jar;C:\Users\WIN 10\.m2\repository\stax\stax-api\1.0.1\stax-api-1.0.1.jar;C:\Users\WIN 10\.m2\repository\org\apache\commons\commons-lang3\3.4\commons-lang3-3.4.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\fastjson\1.2.48\fastjson-1.2.48.jar;C:\Users\WIN 10\.m2\repository\net\sf\json-lib\json-lib\2.4\json-lib-2.4-jdk15.jar;C:\Users\WIN 10\.m2\repository\commons-beanutils\commons-beanutils\1.8.0\commons-beanutils-1.8.0.jar;C:\Users\WIN 10\.m2\repository\commons-collections\commons-collections\3.2.1\commons-collections-3.2.1.jar;C:\Users\WIN 10\.m2\repository\commons-lang\commons-lang\2.5\commons-lang-2.5.jar;C:\Users\WIN 10\.m2\repository\commons-logging\commons-logging\1.1.1\commons-logging-1.1.1.jar;C:\Users\WIN 10\.m2\repository\net\sf\ezmorph\ezmorph\1.0.6\ezmorph-1.0.6.jar;C:\Users\WIN 10\.m2\repository\com\google\code\gson\gson\2.8.2\gson-2.8.2.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\core\jackson-databind\2.9.4\jackson-databind-2.9.4.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\core\jackson-core\2.9.8\jackson-core-2.9.8.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\core\jackson-annotations\2.9.4\jackson-annotations-2.9.4.jar;C:\Users\WIN 10\.m2\repository\com\squareup\okhttp3\okhttp\3.4.1\okhttp-3.4.1.jar;C:\Users\WIN 10\.m2\repository\com\squareup\okio\okio\1.9.0\okio-1.9.0.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter-cache\2.1.3.RELEASE\spring-boot-starter-cache-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\com\google\guava\guava\19.0\guava-19.0.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-context-support\4.3.16.RELEASE\spring-context-support-4.3.16.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-beans\5.1.5.RELEASE\spring-beans-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-context\5.1.5.RELEASE\spring-context-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-aop\5.1.5.RELEASE\spring-aop-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-expression\5.1.5.RELEASE\spring-expression-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\junit\junit\4.12\junit-4.12.jar;C:\Users\WIN 10\.m2\repository\org\reflections\reflections\0.9.10\reflections-0.9.10.jar;C:\Users\WIN 10\.m2\repository\org\javassist\javassist\3.19.0-GA\javassist-3.19.0-GA.jar;C:\Users\WIN 10\.m2\repository\com\google\code\findbugs\annotations\2.0.1\annotations-2.0.1.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-web\5.1.5.RELEASE\spring-web-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\javax\servlet\servlet-api\2.5\servlet-api-2.5.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-annotation-aspectj\1.4.0\sentinel-annotation-aspectj-1.4.0.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-core\1.4.0\sentinel-core-1.4.0.jar;C:\Users\WIN 10\.m2\repository\org\aspectj\aspectjrt\1.9.2\aspectjrt-1.9.2.jar;C:\Users\WIN 10\.m2\repository\org\aspectj\aspectjweaver\1.9.2\aspectjweaver-1.9.2.jar;C:\Users\WIN 10\.m2\repository\org\slf4j\slf4j-api\1.7.25\slf4j-api-1.7.25.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\ahas-sentinel-client\1.0.4\ahas-sentinel-client-1.0.4.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-transport-common\1.4.0\sentinel-transport-common-1.4.0.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-datasource-extension\1.4.0\sentinel-datasource-extension-1.4.0.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-web-servlet\1.4.0\sentinel-web-servlet-1.4.0.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\csp\sentinel-dubbo-adapter\1.4.0\sentinel-dubbo-adapter-1.4.0.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter-web\2.1.3.RELEASE\spring-boot-starter-web-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter-json\2.1.3.RELEASE\spring-boot-starter-json-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jdk8\2.9.8\jackson-datatype-jdk8-2.9.8.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\datatype\jackson-datatype-jsr310\2.9.8\jackson-datatype-jsr310-2.9.8.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\module\jackson-module-parameter-names\2.9.8\jackson-module-parameter-names-2.9.8.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-starter-tomcat\2.1.3.RELEASE\spring-boot-starter-tomcat-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\apache\tomcat\embed\tomcat-embed-core\9.0.16\tomcat-embed-core-9.0.16.jar;C:\Users\WIN 10\.m2\repository\org\apache\tomcat\embed\tomcat-embed-el\9.0.16\tomcat-embed-el-9.0.16.jar;C:\Users\WIN 10\.m2\repository\org\apache\tomcat\embed\tomcat-embed-websocket\9.0.16\tomcat-embed-websocket-9.0.16.jar;C:\Users\WIN 10\.m2\repository\org\hibernate\validator\hibernate-validator\6.0.14.Final\hibernate-validator-6.0.14.Final.jar;C:\Users\WIN 10\.m2\repository\javax\validation\validation-api\2.0.1.Final\validation-api-2.0.1.Final.jar;C:\Users\WIN 10\.m2\repository\org\jboss\logging\jboss-logging\3.3.2.Final\jboss-logging-3.3.2.Final.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\classmate\1.4.0\classmate-1.4.0.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-webmvc\5.1.5.RELEASE\spring-webmvc-5.1.5.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\boot\spring-boot-devtools\2.1.3.RELEASE\spring-boot-devtools-2.1.3.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\projectlombok\lombok\1.18.6\lombok-1.18.6.jar;C:\Users\WIN 10\.m2\repository\redis\clients\jedis\2.9.0\jedis-2.9.0.jar;C:\Users\WIN 10\.m2\repository\org\apache\commons\commons-pool2\2.6.1\commons-pool2-2.6.1.jar;C:\Users\WIN 10\.m2\repository\org\redisson\redisson\3.5.4\redisson-3.5.4.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-common\4.1.33.Final\netty-common-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-codec\4.1.33.Final\netty-codec-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-buffer\4.1.33.Final\netty-buffer-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-transport\4.1.33.Final\netty-transport-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-resolver\4.1.33.Final\netty-resolver-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\io\netty\netty-handler\4.1.33.Final\netty-handler-4.1.33.Final.jar;C:\Users\WIN 10\.m2\repository\javax\cache\cache-api\1.1.0\cache-api-1.1.0.jar;C:\Users\WIN 10\.m2\repository\io\projectreactor\reactor-stream\2.0.8.RELEASE\reactor-stream-2.0.8.RELEASE.jar;C:\Users\WIN 10\.m2\repository\io\projectreactor\reactor-core\3.2.6.RELEASE\reactor-core-3.2.6.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\reactivestreams\reactive-streams\1.0.2\reactive-streams-1.0.2.jar;C:\Users\WIN 10\.m2\repository\com\fasterxml\jackson\dataformat\jackson-dataformat-yaml\2.9.8\jackson-dataformat-yaml-2.9.8.jar;C:\Users\WIN 10\.m2\repository\net\openhft\zero-allocation-hashing\0.8\zero-allocation-hashing-0.8.jar;C:\Users\WIN 10\.m2\repository\net\bytebuddy\byte-buddy\1.9.10\byte-buddy-1.9.10.jar;C:\Users\WIN 10\.m2\repository\org\jodd\jodd-bean\3.7.1\jodd-bean-3.7.1.jar;C:\Users\WIN 10\.m2\repository\org\jodd\jodd-core\3.7.1\jodd-core-3.7.1.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-jdbc\5.0.8.RELEASE\spring-jdbc-5.0.8.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\springframework\spring-tx\5.0.8.RELEASE\spring-tx-5.0.8.RELEASE.jar;C:\Users\WIN 10\.m2\repository\org\mybatis\mybatis\3.4.2\mybatis-3.4.2.jar;C:\Users\WIN 10\.m2\repository\org\mybatis\mybatis-spring\1.3.1\mybatis-spring-1.3.1.jar;C:\Users\WIN 10\.m2\repository\mysql\mysql-connector-java\5.1.41\mysql-connector-java-5.1.41.jar;C:\Users\WIN 10\.m2\repository\com\alibaba\druid\1.0.29\druid-1.0.29.jar;C:\Program Files\Java\jdk1.8.0_102\lib\jconsole.jar;C:\Program Files\Java\jdk1.8.0_102\lib\tools.jar;C:\Users\WIN 10\.m2\repository\cn\hutool\hutool-all\4.1.14\hutool-all-4.1.14.jar;C:\Users\WIN 10\.m2\repository\jaxen\jaxen\1.1.6\jaxen-1.1.6.jar;C:\Users\WIN 10\.m2\repository\org\openjdk\jmh\jmh-core\1.21\jmh-core-1.21.jar;C:\Users\WIN 10\.m2\repository\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;C:\Users\WIN 10\.m2\repository\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar;D:\idea\IntelliJ IDEA 2016.3.2\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain com.test.BenchMark
# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.arrayTraverse
# Parameters: (n = 10)

# Run progress: 0.00% complete, ETA 00:37:20
# Fork: 1 of 2
# Warmup Iteration   1: 269253.345 ops/ms
# Warmup Iteration   2: 276347.381 ops/ms
# Warmup Iteration   3: 251860.415 ops/ms
# Warmup Iteration   4: 253663.464 ops/ms
Iteration   1: 253869.132 ops/ms
Iteration   2: 253979.147 ops/ms
Iteration   3: 254048.787 ops/ms
Iteration   4: 246452.546 ops/ms
Iteration   5: 247090.796 ops/ms
Iteration   6: 245001.900 ops/ms
Iteration   7: 241709.798 ops/ms
Iteration   8: 239876.092 ops/ms
Iteration   9: 247479.915 ops/ms
Iteration  10: 244184.296 ops/ms

# Run progress: 6.25% complete, ETA 00:35:23
# Fork: 2 of 2
# Warmup Iteration   1: 262327.662 ops/ms
# Warmup Iteration   2: 249005.505 ops/ms
# Warmup Iteration   3: 225895.422 ops/ms
# Warmup Iteration   4: 246270.959 ops/ms
Iteration   1: 239307.449 ops/ms
Iteration   2: 249547.283 ops/ms
Iteration   3: 237567.515 ops/ms
Iteration   4: 241927.174 ops/ms
Iteration   5: 241171.284 ops/ms
Iteration   6: 249272.554 ops/ms
Iteration   7: 232713.606 ops/ms
Iteration   8: 236583.256 ops/ms
Iteration   9: 238318.481 ops/ms
Iteration  10: 244700.968 ops/ms


Result "com.test.BenchMark.arrayTraverse":
  244240.099 ±(99.9%) 5260.186 ops/ms [Average]
  (min, avg, max) = (232713.606, 244240.099, 254048.787), stdev = 6057.638
  CI (99.9%): [238979.913, 249500.285] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.arrayTraverse
# Parameters: (n = 40)

# Run progress: 12.50% complete, ETA 00:32:56
# Fork: 1 of 2
# Warmup Iteration   1: 269298.399 ops/ms
# Warmup Iteration   2: 250274.934 ops/ms
# Warmup Iteration   3: 224129.974 ops/ms
# Warmup Iteration   4: 236926.906 ops/ms
Iteration   1: 246589.230 ops/ms
Iteration   2: 240672.448 ops/ms
Iteration   3: 237557.459 ops/ms
Iteration   4: 244917.163 ops/ms
Iteration   5: 243595.372 ops/ms
Iteration   6: 240817.548 ops/ms
Iteration   7: 244004.529 ops/ms
Iteration   8: 243876.568 ops/ms
Iteration   9: 245759.666 ops/ms
Iteration  10: 240356.969 ops/ms

# Run progress: 18.75% complete, ETA 00:30:34
# Fork: 2 of 2
# Warmup Iteration   1: 267381.536 ops/ms
# Warmup Iteration   2: 270898.548 ops/ms
# Warmup Iteration   3: 244377.704 ops/ms
# Warmup Iteration   4: 241881.102 ops/ms
Iteration   1: 251168.528 ops/ms
Iteration   2: 249776.306 ops/ms
Iteration   3: 234549.540 ops/ms
Iteration   4: 246513.541 ops/ms
Iteration   5: 234528.879 ops/ms
Iteration   6: 239595.043 ops/ms
Iteration   7: 236247.700 ops/ms
Iteration   8: 237485.710 ops/ms
Iteration   9: 243017.000 ops/ms
Iteration  10: 244050.446 ops/ms


Result "com.test.BenchMark.arrayTraverse":
  242253.982 ±(99.9%) 4076.939 ops/ms [Average]
  (min, avg, max) = (234528.879, 242253.982, 251168.528), stdev = 4695.009
  CI (99.9%): [238177.043, 246330.921] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.arrayTraverse
# Parameters: (n = 70)

# Run progress: 25.00% complete, ETA 00:28:12
# Fork: 1 of 2
# Warmup Iteration   1: 264112.348 ops/ms
# Warmup Iteration   2: 264851.973 ops/ms
# Warmup Iteration   3: 241546.715 ops/ms
# Warmup Iteration   4: 247411.887 ops/ms
Iteration   1: 242990.095 ops/ms
Iteration   2: 237809.590 ops/ms
Iteration   3: 241336.730 ops/ms
Iteration   4: 245719.341 ops/ms
Iteration   5: 249942.333 ops/ms
Iteration   6: 242746.842 ops/ms
Iteration   7: 243580.100 ops/ms
Iteration   8: 226147.618 ops/ms
Iteration   9: 234889.727 ops/ms
Iteration  10: 225346.636 ops/ms

# Run progress: 31.25% complete, ETA 00:25:51
# Fork: 2 of 2
# Warmup Iteration   1: 268809.003 ops/ms
# Warmup Iteration   2: 269831.920 ops/ms
# Warmup Iteration   3: 249327.328 ops/ms
# Warmup Iteration   4: 246486.802 ops/ms
Iteration   1: 242417.448 ops/ms
Iteration   2: 241696.637 ops/ms
Iteration   3: 242502.680 ops/ms
Iteration   4: 248167.064 ops/ms
Iteration   5: 246509.815 ops/ms
Iteration   6: 246130.289 ops/ms
Iteration   7: 245738.974 ops/ms
Iteration   8: 240680.595 ops/ms
Iteration   9: 243761.610 ops/ms
Iteration  10: 229405.020 ops/ms


Result "com.test.BenchMark.arrayTraverse":
  240875.957 ±(99.9%) 5997.232 ops/ms [Average]
  (min, avg, max) = (225346.636, 240875.957, 249942.333), stdev = 6906.421
  CI (99.9%): [234878.725, 246873.189] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.arrayTraverse
# Parameters: (n = 100)

# Run progress: 37.50% complete, ETA 00:23:29
# Fork: 1 of 2
# Warmup Iteration   1: 260855.900 ops/ms
# Warmup Iteration   2: 248468.794 ops/ms
# Warmup Iteration   3: 237650.150 ops/ms
# Warmup Iteration   4: 242552.490 ops/ms
Iteration   1: 235307.636 ops/ms
Iteration   2: 231372.523 ops/ms
Iteration   3: 242025.734 ops/ms
Iteration   4: 237780.791 ops/ms
Iteration   5: 244922.372 ops/ms
Iteration   6: 241202.941 ops/ms
Iteration   7: 236031.591 ops/ms
Iteration   8: 245637.821 ops/ms
Iteration   9: 243341.859 ops/ms
Iteration  10: 240355.816 ops/ms

# Run progress: 43.75% complete, ETA 00:21:08
# Fork: 2 of 2
# Warmup Iteration   1: 265750.548 ops/ms
# Warmup Iteration   2: 265914.164 ops/ms
# Warmup Iteration   3: 238631.683 ops/ms
# Warmup Iteration   4: 245944.458 ops/ms
Iteration   1: 252724.300 ops/ms
Iteration   2: 253149.800 ops/ms
Iteration   3: 252617.967 ops/ms
Iteration   4: 252913.232 ops/ms
Iteration   5: 253192.094 ops/ms
Iteration   6: 253042.718 ops/ms
Iteration   7: 253116.823 ops/ms
Iteration   8: 252940.270 ops/ms
Iteration   9: 252573.306 ops/ms
Iteration  10: 252899.513 ops/ms


Result "com.test.BenchMark.arrayTraverse":
  246357.455 ±(99.9%) 6457.011 ops/ms [Average]
  (min, avg, max) = (231372.523, 246357.455, 253192.094), stdev = 7435.904
  CI (99.9%): [239900.444, 252814.467] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.listTraverse
# Parameters: (n = 10)

# Run progress: 50.00% complete, ETA 00:18:47
# Fork: 1 of 2
# Warmup Iteration   1: 30270.049 ops/ms
# Warmup Iteration   2: 28988.886 ops/ms
# Warmup Iteration   3: 30441.188 ops/ms
# Warmup Iteration   4: 30563.294 ops/ms
Iteration   1: 30571.336 ops/ms
Iteration   2: 30518.011 ops/ms
Iteration   3: 30590.535 ops/ms
Iteration   4: 30625.778 ops/ms
Iteration   5: 29536.554 ops/ms
Iteration   6: 29981.915 ops/ms
Iteration   7: 29427.949 ops/ms
Iteration   8: 27527.321 ops/ms
Iteration   9: 29081.074 ops/ms
Iteration  10: 29920.047 ops/ms

# Run progress: 56.25% complete, ETA 00:16:26
# Fork: 2 of 2
# Warmup Iteration   1: 39903.596 ops/ms
# Warmup Iteration   2: 33049.171 ops/ms
# Warmup Iteration   3: 32438.386 ops/ms
# Warmup Iteration   4: 32203.902 ops/ms
Iteration   1: 32502.511 ops/ms
Iteration   2: 32463.154 ops/ms
Iteration   3: 32466.562 ops/ms
Iteration   4: 32490.753 ops/ms
Iteration   5: 27798.456 ops/ms
Iteration   6: 30851.689 ops/ms
Iteration   7: 32192.946 ops/ms
Iteration   8: 31227.671 ops/ms
Iteration   9: 31584.272 ops/ms
Iteration  10: 29651.929 ops/ms


Result "com.test.BenchMark.listTraverse":
  30550.523 ±(99.9%) 1289.793 ops/ms [Average]
  (min, avg, max) = (27527.321, 30550.523, 32502.511), stdev = 1485.328
  CI (99.9%): [29260.730, 31840.317] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.listTraverse
# Parameters: (n = 40)

# Run progress: 62.50% complete, ETA 00:14:05
# Fork: 1 of 2
# Warmup Iteration   1: 5547.538 ops/ms
# Warmup Iteration   2: 5666.627 ops/ms
# Warmup Iteration   3: 5411.807 ops/ms
# Warmup Iteration   4: 5428.918 ops/ms
Iteration   1: 5516.569 ops/ms
Iteration   2: 5254.293 ops/ms
Iteration   3: 5160.437 ops/ms
Iteration   4: 5402.370 ops/ms
Iteration   5: 5402.447 ops/ms
Iteration   6: 5351.434 ops/ms
Iteration   7: 5122.991 ops/ms
Iteration   8: 5015.266 ops/ms
Iteration   9: 5006.287 ops/ms
Iteration  10: 5194.826 ops/ms

# Run progress: 68.75% complete, ETA 00:11:44
# Fork: 2 of 2
# Warmup Iteration   1: 5721.454 ops/ms
# Warmup Iteration   2: 5200.201 ops/ms
# Warmup Iteration   3: 5332.249 ops/ms
# Warmup Iteration   4: 5005.480 ops/ms
Iteration   1: 5136.291 ops/ms
Iteration   2: 5173.977 ops/ms
Iteration   3: 5231.173 ops/ms
Iteration   4: 5317.605 ops/ms
Iteration   5: 5294.731 ops/ms
Iteration   6: 5250.654 ops/ms
Iteration   7: 5211.670 ops/ms
Iteration   8: 5508.196 ops/ms
Iteration   9: 5554.692 ops/ms
Iteration  10: 5564.351 ops/ms


Result "com.test.BenchMark.listTraverse":
  5283.513 ±(99.9%) 145.369 ops/ms [Average]
  (min, avg, max) = (5006.287, 5283.513, 5564.351), stdev = 167.407
  CI (99.9%): [5138.144, 5428.882] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.listTraverse
# Parameters: (n = 70)

# Run progress: 75.00% complete, ETA 00:09:23
# Fork: 1 of 2
# Warmup Iteration   1: 1661.668 ops/ms
# Warmup Iteration   2: 1656.252 ops/ms
# Warmup Iteration   3: 1183.511 ops/ms
# Warmup Iteration   4: 1422.503 ops/ms
Iteration   1: 1595.955 ops/ms
Iteration   2: 1652.515 ops/ms
Iteration   3: 1640.605 ops/ms
Iteration   4: 1650.898 ops/ms
Iteration   5: 1606.025 ops/ms
Iteration   6: 1625.966 ops/ms
Iteration   7: 1588.238 ops/ms
Iteration   8: 1530.747 ops/ms
Iteration   9: 1493.374 ops/ms
Iteration  10: 1538.245 ops/ms

# Run progress: 81.25% complete, ETA 00:07:02
# Fork: 2 of 2
# Warmup Iteration   1: 1665.155 ops/ms
# Warmup Iteration   2: 1608.146 ops/ms
# Warmup Iteration   3: 1628.850 ops/ms
# Warmup Iteration   4: 1592.705 ops/ms
Iteration   1: 1619.602 ops/ms
Iteration   2: 1647.853 ops/ms
Iteration   3: 1559.266 ops/ms
Iteration   4: 1602.846 ops/ms
Iteration   5: 1600.740 ops/ms
Iteration   6: 1537.869 ops/ms
Iteration   7: 1603.596 ops/ms
Iteration   8: 1626.688 ops/ms
Iteration   9: 1612.564 ops/ms
Iteration  10: 1637.907 ops/ms


Result "com.test.BenchMark.listTraverse":
  1598.575 ±(99.9%) 38.999 ops/ms [Average]
  (min, avg, max) = (1493.374, 1598.575, 1652.515), stdev = 44.911
  CI (99.9%): [1559.576, 1637.574] (assumes normal distribution)


# JMH version: 1.21
# VM version: JDK 1.8.0_102, Java HotSpot(TM) 64-Bit Server VM, 25.102-b14
# VM invoker: C:\Program Files\Java\jdk1.8.0_102\jre\bin\java.exe
# VM options: -Didea.launcher.port=7533 -Didea.launcher.bin.path=D:\idea\IntelliJ IDEA 2016.3.2\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 10 s each
# Measurement: 10 iterations, 10 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.test.BenchMark.listTraverse
# Parameters: (n = 100)

# Run progress: 87.50% complete, ETA 00:04:41
# Fork: 1 of 2
# Warmup Iteration   1: 703.245 ops/ms
# Warmup Iteration   2: 717.354 ops/ms
# Warmup Iteration   3: 713.743 ops/ms
# Warmup Iteration   4: 670.332 ops/ms
Iteration   1: 712.720 ops/ms
Iteration   2: 712.210 ops/ms
Iteration   3: 704.290 ops/ms
Iteration   4: 713.352 ops/ms
Iteration   5: 697.913 ops/ms
Iteration   6: 697.760 ops/ms
Iteration   7: 705.870 ops/ms
Iteration   8: 676.133 ops/ms
Iteration   9: 613.763 ops/ms
Iteration  10: 710.359 ops/ms

# Run progress: 93.75% complete, ETA 00:02:20
# Fork: 2 of 2
# Warmup Iteration   1: 712.607 ops/ms
# Warmup Iteration   2: 720.853 ops/ms
# Warmup Iteration   3: 600.600 ops/ms
# Warmup Iteration   4: 681.508 ops/ms
Iteration   1: 646.139 ops/ms
Iteration   2: 712.554 ops/ms
Iteration   3: 718.939 ops/ms
Iteration   4: 717.526 ops/ms
Iteration   5: 657.281 ops/ms
Iteration   6: 677.377 ops/ms
Iteration   7: 668.686 ops/ms
Iteration   8: 656.218 ops/ms
Iteration   9: 692.389 ops/ms
Iteration  10: 689.929 ops/ms


Result "com.test.BenchMark.listTraverse":
  689.070 ±(99.9%) 24.717 ops/ms [Average]
  (min, avg, max) = (613.763, 689.070, 718.939), stdev = 28.464
  CI (99.9%): [664.353, 713.787] (assumes normal distribution)


# Run complete. Total time: 00:37:34

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                (n)   Mode  Cnt       Score      Error   Units
BenchMark.arrayTraverse   10  thrpt   20  244240.099 ± 5260.186  ops/ms
BenchMark.arrayTraverse   40  thrpt   20  242253.982 ± 4076.939  ops/ms
BenchMark.arrayTraverse   70  thrpt   20  240875.957 ± 5997.232  ops/ms
BenchMark.arrayTraverse  100  thrpt   20  246357.455 ± 6457.011  ops/ms
BenchMark.listTraverse    10  thrpt   20   30550.523 ± 1289.793  ops/ms
BenchMark.listTraverse    40  thrpt   20    5283.513 ±  145.369  ops/ms
BenchMark.listTraverse    70  thrpt   20    1598.575 ±   38.999  ops/ms
BenchMark.listTraverse   100  thrpt   20     689.070 ±   24.717  ops/ms

Process finished with exit code 0

报告很长,因为这里的n有四种情况,然后有两个 @Benchmark 方法,因此会进行8次测试。

大多数情况只需要关注最下面的结果。

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

六.文献参考

https://www.cnblogs.com/fightfordream/p/9353002.html

https://blog.csdn.net/lxbjkben/article/details/79410740

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章