微基準測試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

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