使用JMH作Benchmark基準測試

BenchMark介紹

最近大佬叫我作下Benchmark,以前一直沒接觸過,順便學習一波。mysql

BenchMark 又叫作基準測試,主要用來測試一些方法的性能,能夠根據不一樣的參數以不一樣的單位進行計算(例如可使用吞吐量爲單位,也可使用平均時間做爲單位,在 BenchmarkMode 裏面進行調整)。web

開始前的步驟

項目使用的是 Maven,所以只要對 pom.xml 添加依賴便可。spring

<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 的遍歷的性能差異,當時以一種不太穩當的方法進行測試,致使沒法獲得比較好的結果,恰好這裏可使用這兩個來進行比較。sql

代碼

package com.psd.benchmark;

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;

/**
 * Author: Shadowdsp
 * Date: 18/07/22
 */

@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;

    @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(BenchMark.class.getSimpleName()).build();
        new Runner(options).run();
    }
}

報告

E:\Java\JDK8\bin\java "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin" -Dfile.encoding=UTF-8 -classpath E:\Java\JDK8\jre\lib\charsets.jar;E:\Java\JDK8\jre\lib\deploy.jar;E:\Java\JDK8\jre\lib\ext\access-bridge-64.jar;E:\Java\JDK8\jre\lib\ext\cldrdata.jar;E:\Java\JDK8\jre\lib\ext\dnsns.jar;E:\Java\JDK8\jre\lib\ext\jaccess.jar;E:\Java\JDK8\jre\lib\ext\jfxrt.jar;E:\Java\JDK8\jre\lib\ext\localedata.jar;E:\Java\JDK8\jre\lib\ext\nashorn.jar;E:\Java\JDK8\jre\lib\ext\sunec.jar;E:\Java\JDK8\jre\lib\ext\sunjce_provider.jar;E:\Java\JDK8\jre\lib\ext\sunmscapi.jar;E:\Java\JDK8\jre\lib\ext\sunpkcs11.jar;E:\Java\JDK8\jre\lib\ext\zipfs.jar;E:\Java\JDK8\jre\lib\javaws.jar;E:\Java\JDK8\jre\lib\jce.jar;E:\Java\JDK8\jre\lib\jfr.jar;E:\Java\JDK8\jre\lib\jfxswt.jar;E:\Java\JDK8\jre\lib\jsse.jar;E:\Java\JDK8\jre\lib\management-agent.jar;E:\Java\JDK8\jre\lib\plugin.jar;E:\Java\JDK8\jre\lib\resources.jar;E:\Java\JDK8\jre\lib\rt.jar;E:\Java\IdeaProjects\Warehouse\target\classes;E:\Java\maven\LocalWarehouse\junit\junit\4.11\junit-4.11.jar;E:\Java\maven\LocalWarehouse\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-core\4.0.2.RELEASE\spring-core-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\commons-logging\commons-logging\1.1.3\commons-logging-1.1.3.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-web\4.0.2.RELEASE\spring-web-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-beans\4.0.2.RELEASE\spring-beans-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-context\4.0.2.RELEASE\spring-context-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-oxm\4.0.2.RELEASE\spring-oxm-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-tx\4.0.2.RELEASE\spring-tx-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-jdbc\4.0.2.RELEASE\spring-jdbc-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-webmvc\4.0.2.RELEASE\spring-webmvc-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-expression\4.0.2.RELEASE\spring-expression-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-aop\4.0.2.RELEASE\spring-aop-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-context-support\4.0.2.RELEASE\spring-context-support-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\springframework\spring-test\4.0.2.RELEASE\spring-test-4.0.2.RELEASE.jar;E:\Java\maven\LocalWarehouse\org\mybatis\mybatis\3.2.6\mybatis-3.2.6.jar;E:\Java\maven\LocalWarehouse\org\mybatis\mybatis-spring\1.2.2\mybatis-spring-1.2.2.jar;E:\Java\maven\LocalWarehouse\javax\javaee-api\7.0\javaee-api-7.0.jar;E:\Java\maven\LocalWarehouse\com\sun\mail\javax.mail\1.5.0\javax.mail-1.5.0.jar;E:\Java\maven\LocalWarehouse\javax\activation\activation\1.1\activation-1.1.jar;E:\Java\maven\LocalWarehouse\mysql\mysql-connector-java\5.1.30\mysql-connector-java-5.1.30.jar;E:\Java\maven\LocalWarehouse\commons-dbcp\commons-dbcp\1.2.2\commons-dbcp-1.2.2.jar;E:\Java\maven\LocalWarehouse\commons-pool\commons-pool\1.3\commons-pool-1.3.jar;E:\Java\maven\LocalWarehouse\jstl\jstl\1.2\jstl-1.2.jar;E:\Java\maven\LocalWarehouse\log4j\log4j\1.2.17\log4j-1.2.17.jar;E:\Java\maven\LocalWarehouse\com\alibaba\fastjson\1.1.41\fastjson-1.1.41.jar;E:\Java\maven\LocalWarehouse\org\slf4j\slf4j-api\1.7.7\slf4j-api-1.7.7.jar;E:\Java\maven\LocalWarehouse\org\slf4j\slf4j-log4j12\1.7.7\slf4j-log4j12-1.7.7.jar;E:\Java\maven\LocalWarehouse\org\codehaus\jackson\jackson-mapper-asl\1.9.13\jackson-mapper-asl-1.9.13.jar;E:\Java\maven\LocalWarehouse\org\codehaus\jackson\jackson-core-asl\1.9.13\jackson-core-asl-1.9.13.jar;E:\Java\maven\LocalWarehouse\commons-fileupload\commons-fileupload\1.3.1\commons-fileupload-1.3.1.jar;E:\Java\maven\LocalWarehouse\commons-io\commons-io\2.4\commons-io-2.4.jar;E:\Java\maven\LocalWarehouse\commons-codec\commons-codec\1.9\commons-codec-1.9.jar;E:\Java\maven\LocalWarehouse\org\junit\jupiter\junit-jupiter-api\5.3.0-M1\junit-jupiter-api-5.3.0-M1.jar;E:\Java\maven\LocalWarehouse\org\apiguardian\apiguardian-api\1.0.0\apiguardian-api-1.0.0.jar;E:\Java\maven\LocalWarehouse\org\opentest4j\opentest4j\1.1.0\opentest4j-1.1.0.jar;E:\Java\maven\LocalWarehouse\org\junit\platform\junit-platform-commons\1.3.0-M1\junit-platform-commons-1.3.0-M1.jar;E:\Java\maven\LocalWarehouse\org\openjdk\jmh\jmh-core\1.19\jmh-core-1.19.jar;E:\Java\maven\LocalWarehouse\net\sf\jopt-simple\jopt-simple\4.6\jopt-simple-4.6.jar;E:\Java\maven\LocalWarehouse\org\apache\commons\commons-math3\3.2\commons-math3-3.2.jar com.psd.benchmark.BenchMark
# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.arrayTraverse
# Parameters: (n = 10)

# Run progress: 0.00% complete, ETA 00:03:44
# Fork: 1 of 2
# Warmup Iteration   1: 189538.902 ops/ms
# Warmup Iteration   2: 287165.702 ops/ms
# Warmup Iteration   3: 282388.510 ops/ms
# Warmup Iteration   4: 277296.753 ops/ms
Iteration   1: 288687.174 ops/ms
Iteration   2: 277046.541 ops/ms
Iteration   3: 288680.458 ops/ms
Iteration   4: 279775.705 ops/ms
Iteration   5: 289098.257 ops/ms
Iteration   6: 287462.515 ops/ms
Iteration   7: 255330.788 ops/ms
Iteration   8: 282631.894 ops/ms
Iteration   9: 277038.372 ops/ms
Iteration  10: 277690.784 ops/ms

# Run progress: 6.25% complete, ETA 00:03:42
# Fork: 2 of 2
# Warmup Iteration   1: 286568.900 ops/ms
# Warmup Iteration   2: 288014.591 ops/ms
# Warmup Iteration   3: 281790.934 ops/ms
# Warmup Iteration   4: 279647.288 ops/ms
Iteration   1: 280839.175 ops/ms
Iteration   2: 289208.462 ops/ms
Iteration   3: 282724.949 ops/ms
Iteration   4: 289762.265 ops/ms
Iteration   5: 284551.820 ops/ms
Iteration   6: 283700.745 ops/ms
Iteration   7: 261083.800 ops/ms
Iteration   8: 283651.988 ops/ms
Iteration   9: 284418.725 ops/ms
Iteration  10: 282418.733 ops/ms


Result "com.psd.benchmark.BenchMark.arrayTraverse":
  281290.158 ±(99.9%) 7750.303 ops/ms [Average]
  (min, avg, max) = (255330.788, 281290.158, 289762.265), stdev = 8925.261
  CI (99.9%): [273539.854, 289040.461] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.arrayTraverse
# Parameters: (n = 40)

# Run progress: 12.50% complete, ETA 00:03:27
# Fork: 1 of 2
# Warmup Iteration   1: 277185.994 ops/ms
# Warmup Iteration   2: 277343.966 ops/ms
# Warmup Iteration   3: 289105.366 ops/ms
# Warmup Iteration   4: 281931.930 ops/ms
Iteration   1: 279532.380 ops/ms
Iteration   2: 278419.091 ops/ms
Iteration   3: 281165.591 ops/ms
Iteration   4: 288999.045 ops/ms
Iteration   5: 277378.462 ops/ms
Iteration   6: 275360.726 ops/ms
Iteration   7: 282858.013 ops/ms
Iteration   8: 283601.524 ops/ms
Iteration   9: 279043.295 ops/ms
Iteration  10: 279976.466 ops/ms

# Run progress: 18.75% complete, ETA 00:03:12
# Fork: 2 of 2
# Warmup Iteration   1: 284211.718 ops/ms
# Warmup Iteration   2: 287327.346 ops/ms
# Warmup Iteration   3: 268548.012 ops/ms
# Warmup Iteration   4: 289429.098 ops/ms
Iteration   1: 283348.446 ops/ms
Iteration   2: 262579.782 ops/ms
Iteration   3: 283534.897 ops/ms
Iteration   4: 266160.111 ops/ms
Iteration   5: 289614.776 ops/ms
Iteration   6: 274270.699 ops/ms
Iteration   7: 267829.186 ops/ms
Iteration   8: 279612.742 ops/ms
Iteration   9: 283569.117 ops/ms
Iteration  10: 288172.441 ops/ms


Result "com.psd.benchmark.BenchMark.arrayTraverse":
  279251.339 ±(99.9%) 6287.385 ops/ms [Average]
  (min, avg, max) = (262579.782, 279251.339, 289614.776), stdev = 7240.561
  CI (99.9%): [272963.955, 285538.724] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.arrayTraverse
# Parameters: (n = 70)

# Run progress: 25.00% complete, ETA 00:02:57
# Fork: 1 of 2
# Warmup Iteration   1: 276172.253 ops/ms
# Warmup Iteration   2: 284624.007 ops/ms
# Warmup Iteration   3: 288356.101 ops/ms
# Warmup Iteration   4: 284278.064 ops/ms
Iteration   1: 287831.035 ops/ms
Iteration   2: 286518.388 ops/ms
Iteration   3: 287016.992 ops/ms
Iteration   4: 282654.336 ops/ms
Iteration   5: 287899.254 ops/ms
Iteration   6: 287299.594 ops/ms
Iteration   7: 284624.713 ops/ms
Iteration   8: 287280.777 ops/ms
Iteration   9: 268079.560 ops/ms
Iteration  10: 266327.469 ops/ms

# Run progress: 31.25% complete, ETA 00:02:42
# Fork: 2 of 2
# Warmup Iteration   1: 282831.765 ops/ms
# Warmup Iteration   2: 271396.073 ops/ms
# Warmup Iteration   3: 280114.449 ops/ms
# Warmup Iteration   4: 272365.705 ops/ms
Iteration   1: 287276.286 ops/ms
Iteration   2: 258473.510 ops/ms
Iteration   3: 287822.759 ops/ms
Iteration   4: 281849.137 ops/ms
Iteration   5: 281739.415 ops/ms
Iteration   6: 271390.808 ops/ms
Iteration   7: 279252.964 ops/ms
Iteration   8: 280445.016 ops/ms
Iteration   9: 287019.516 ops/ms
Iteration  10: 283679.804 ops/ms


Result "com.psd.benchmark.BenchMark.arrayTraverse":
  281224.067 ±(99.9%) 7376.077 ops/ms [Average]
  (min, avg, max) = (258473.510, 281224.067, 287899.254), stdev = 8494.301
  CI (99.9%): [273847.990, 288600.143] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.arrayTraverse
# Parameters: (n = 100)

# Run progress: 37.50% complete, ETA 00:02:27
# Fork: 1 of 2
# Warmup Iteration   1: 277758.992 ops/ms
# Warmup Iteration   2: 283193.840 ops/ms
# Warmup Iteration   3: 280441.005 ops/ms
# Warmup Iteration   4: 284059.500 ops/ms
Iteration   1: 288156.207 ops/ms
Iteration   2: 277402.478 ops/ms
Iteration   3: 274760.100 ops/ms
Iteration   4: 280052.747 ops/ms
Iteration   5: 261148.816 ops/ms
Iteration   6: 281093.340 ops/ms
Iteration   7: 278472.671 ops/ms
Iteration   8: 257387.342 ops/ms
Iteration   9: 258938.869 ops/ms
Iteration  10: 281241.529 ops/ms

# Run progress: 43.75% complete, ETA 00:02:12
# Fork: 2 of 2
# Warmup Iteration   1: 261991.159 ops/ms
# Warmup Iteration   2: 272490.286 ops/ms
# Warmup Iteration   3: 283308.053 ops/ms
# Warmup Iteration   4: 262856.702 ops/ms
Iteration   1: 283588.427 ops/ms
Iteration   2: 289665.875 ops/ms
Iteration   3: 242227.467 ops/ms
Iteration   4: 235915.418 ops/ms
Iteration   5: 282235.546 ops/ms
Iteration   6: 262060.151 ops/ms
Iteration   7: 249476.606 ops/ms
Iteration   8: 289452.132 ops/ms
Iteration   9: 249939.347 ops/ms
Iteration  10: 268307.387 ops/ms


Result "com.psd.benchmark.BenchMark.arrayTraverse":
  269576.123 ±(99.9%) 14237.446 ops/ms [Average]
  (min, avg, max) = (235915.418, 269576.123, 289665.875), stdev = 16395.864
  CI (99.9%): [255338.677, 283813.569] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.listTraverse
# Parameters: (n = 10)

# Run progress: 50.00% complete, ETA 00:01:58
# Fork: 1 of 2
# Warmup Iteration   1: 44140.774 ops/ms
# Warmup Iteration   2: 32207.674 ops/ms
# Warmup Iteration   3: 36260.862 ops/ms
# Warmup Iteration   4: 32678.534 ops/ms
Iteration   1: 35846.579 ops/ms
Iteration   2: 34837.967 ops/ms
Iteration   3: 36439.906 ops/ms
Iteration   4: 36522.320 ops/ms
Iteration   5: 35112.493 ops/ms
Iteration   6: 35687.937 ops/ms
Iteration   7: 35727.530 ops/ms
Iteration   8: 31676.889 ops/ms
Iteration   9: 36219.853 ops/ms
Iteration  10: 35857.764 ops/ms

# Run progress: 56.25% complete, ETA 00:01:43
# Fork: 2 of 2
# Warmup Iteration   1: 34479.354 ops/ms
# Warmup Iteration   2: 34805.614 ops/ms
# Warmup Iteration   3: 37839.045 ops/ms
# Warmup Iteration   4: 38778.482 ops/ms
Iteration   1: 37184.558 ops/ms
Iteration   2: 35340.593 ops/ms
Iteration   3: 37976.310 ops/ms
Iteration   4: 39359.895 ops/ms
Iteration   5: 37142.984 ops/ms
Iteration   6: 38973.376 ops/ms
Iteration   7: 38609.058 ops/ms
Iteration   8: 39516.419 ops/ms
Iteration   9: 33589.403 ops/ms
Iteration  10: 37153.584 ops/ms


Result "com.psd.benchmark.BenchMark.listTraverse":
  36438.771 ±(99.9%) 1680.987 ops/ms [Average]
  (min, avg, max) = (31676.889, 36438.771, 39516.419), stdev = 1935.828
  CI (99.9%): [34757.784, 38119.758] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.listTraverse
# Parameters: (n = 40)

# Run progress: 62.50% complete, ETA 00:01:28
# Fork: 1 of 2
# Warmup Iteration   1: 6381.367 ops/ms
# Warmup Iteration   2: 6267.589 ops/ms
# Warmup Iteration   3: 6070.546 ops/ms
# Warmup Iteration   4: 6311.543 ops/ms
Iteration   1: 6294.215 ops/ms
Iteration   2: 6221.013 ops/ms
Iteration   3: 6196.371 ops/ms
Iteration   4: 5960.573 ops/ms
Iteration   5: 5748.201 ops/ms
Iteration   6: 5494.775 ops/ms
Iteration   7: 5594.778 ops/ms
Iteration   8: 6345.496 ops/ms
Iteration   9: 6141.148 ops/ms
Iteration  10: 6017.750 ops/ms

# Run progress: 68.75% complete, ETA 00:01:13
# Fork: 2 of 2
# Warmup Iteration   1: 6369.814 ops/ms
# Warmup Iteration   2: 6258.675 ops/ms
# Warmup Iteration   3: 5802.971 ops/ms
# Warmup Iteration   4: 6028.703 ops/ms
Iteration   1: 6192.258 ops/ms
Iteration   2: 5966.093 ops/ms
Iteration   3: 5958.597 ops/ms
Iteration   4: 6171.185 ops/ms
Iteration   5: 5617.002 ops/ms
Iteration   6: 5387.913 ops/ms
Iteration   7: 5299.407 ops/ms
Iteration   8: 5939.628 ops/ms
Iteration   9: 5640.087 ops/ms
Iteration  10: 6057.939 ops/ms


Result "com.psd.benchmark.BenchMark.listTraverse":
  5912.221 ±(99.9%) 271.819 ops/ms [Average]
  (min, avg, max) = (5299.407, 5912.221, 6345.496), stdev = 313.027
  CI (99.9%): [5640.403, 6184.040] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.listTraverse
# Parameters: (n = 70)

# Run progress: 75.00% complete, ETA 00:00:59
# Fork: 1 of 2
# Warmup Iteration   1: 1904.675 ops/ms
# Warmup Iteration   2: 1829.190 ops/ms
# Warmup Iteration   3: 1799.166 ops/ms
# Warmup Iteration   4: 1823.508 ops/ms
Iteration   1: 1483.423 ops/ms
Iteration   2: 1733.061 ops/ms
Iteration   3: 1752.878 ops/ms
Iteration   4: 1877.448 ops/ms
Iteration   5: 1748.907 ops/ms
Iteration   6: 1836.011 ops/ms
Iteration   7: 1830.008 ops/ms
Iteration   8: 1733.991 ops/ms
Iteration   9: 1821.246 ops/ms
Iteration  10: 1827.086 ops/ms

# Run progress: 81.25% complete, ETA 00:00:44
# Fork: 2 of 2
# Warmup Iteration   1: 1858.409 ops/ms
# Warmup Iteration   2: 1816.699 ops/ms
# Warmup Iteration   3: 1810.298 ops/ms
# Warmup Iteration   4: 1704.668 ops/ms
Iteration   1: 1772.384 ops/ms
Iteration   2: 1619.981 ops/ms
Iteration   3: 1754.014 ops/ms
Iteration   4: 1767.706 ops/ms
Iteration   5: 1706.000 ops/ms
Iteration   6: 1646.038 ops/ms
Iteration   7: 1789.584 ops/ms
Iteration   8: 1746.964 ops/ms
Iteration   9: 1785.779 ops/ms
Iteration  10: 1813.610 ops/ms


Result "com.psd.benchmark.BenchMark.listTraverse":
  1752.306 ±(99.9%) 77.143 ops/ms [Average]
  (min, avg, max) = (1483.423, 1752.306, 1877.448), stdev = 88.838
  CI (99.9%): [1675.163, 1829.449] (assumes normal distribution)


# JMH version: 1.19
# VM version: JDK 1.8.0_144, VM 25.144-b01
# VM invoker: E:\Java\JDK8\jre\bin\java.exe
# VM options: -javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\lib\idea_rt.jar=6182:C:\Program Files\JetBrains\IntelliJ IDEA 2017.3.1\bin -Dfile.encoding=UTF-8
# Warmup: 4 iterations, 1 s each
# Measurement: 10 iterations, 1 s each
# Timeout: 10 min per iteration
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Throughput, ops/time
# Benchmark: com.psd.benchmark.BenchMark.listTraverse
# Parameters: (n = 100)

# Run progress: 87.50% complete, ETA 00:00:29
# Fork: 1 of 2
# Warmup Iteration   1: 784.637 ops/ms
# Warmup Iteration   2: 803.586 ops/ms
# Warmup Iteration   3: 780.992 ops/ms
# Warmup Iteration   4: 812.284 ops/ms
Iteration   1: 771.280 ops/ms
Iteration   2: 725.038 ops/ms
Iteration   3: 781.465 ops/ms
Iteration   4: 753.939 ops/ms
Iteration   5: 753.920 ops/ms
Iteration   6: 813.238 ops/ms
Iteration   7: 778.423 ops/ms
Iteration   8: 809.902 ops/ms
Iteration   9: 769.837 ops/ms
Iteration  10: 767.709 ops/ms

# Run progress: 93.75% complete, ETA 00:00:14
# Fork: 2 of 2
# Warmup Iteration   1: 703.812 ops/ms
# Warmup Iteration   2: 752.538 ops/ms
# Warmup Iteration   3: 774.776 ops/ms
# Warmup Iteration   4: 813.269 ops/ms
Iteration   1: 796.985 ops/ms
Iteration   2: 687.697 ops/ms
Iteration   3: 808.395 ops/ms
Iteration   4: 736.341 ops/ms
Iteration   5: 761.328 ops/ms
Iteration   6: 746.422 ops/ms
Iteration   7: 767.855 ops/ms
Iteration   8: 814.670 ops/ms
Iteration   9: 772.441 ops/ms
Iteration  10: 731.986 ops/ms


Result "com.psd.benchmark.BenchMark.listTraverse":
  767.444 ±(99.9%) 28.363 ops/ms [Average]
  (min, avg, max) = (687.697, 767.444, 814.670), stdev = 32.662
  CI (99.9%): [739.081, 795.806] (assumes normal distribution)


# Run complete. Total time: 00:03:56
(通常只須要關注這下面的東西)

Benchmark                (n)   Mode  Cnt       Score       Error   Units
BenchMark.arrayTraverse   10  thrpt   20  281290.158 ±  7750.303  ops/ms
BenchMark.arrayTraverse   40  thrpt   20  279251.339 ±  6287.385  ops/ms
BenchMark.arrayTraverse   70  thrpt   20  281224.067 ±  7376.077  ops/ms
BenchMark.arrayTraverse  100  thrpt   20  269576.123 ± 14237.446  ops/ms
BenchMark.listTraverse    10  thrpt   20   36438.771 ±  1680.987  ops/ms
BenchMark.listTraverse    40  thrpt   20    5912.221 ±   271.819  ops/ms
BenchMark.listTraverse    70  thrpt   20    1752.306 ±    77.143  ops/ms
BenchMark.listTraverse   100  thrpt   20     767.444 ±    28.363  ops/ms

Process finished with exit code 0

報告很長,由於這裏的n有四種狀況,而後有兩個 @Benchmark 方法,所以會進行8次測試。express

大多數狀況只須要關注最下面的結果。apache

能夠結合 Score 和 Unit 這兩列,看到方法的效率。這裏顯然 arrayTraverse 的效率比 listTraverse 的高不少,由於 Unit 單位是 ops/ms,即單位時間內執行的操做數。因此顯然在遍歷的時候,ArrayList的效率是比LinkedList高的。json

註解介紹

@BenchmarkMode

Mode 表示 JMH 進行 Benchmark 時所使用的模式。一般是測量的維度不一樣,或是測量的方式不一樣。目前 JMH 共有四種模式:api

  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次。

相關文章
相關標籤/搜索