JMH:基準測試工具套件-應用

1.背景

多線程性能測試

JMH:簡介

JMH is a Java harness for building, running, and analysing nano/micro/milli/macro benchmarks written in Java and other languages targetting the JVM,

由簡介可知,JMH不止能對Java語言做基準測試,還能對運行在JVM上的其他語言做基準測試。而且可以分析到納秒級別。

2.生成maven工程

推薦用法通過命令行創建,構建和運行JMH基準測試。

執行如下命令:

mvn archetype:generate -DinteractiveMode=false -DarchetypeGroupId=org.openjdk.jmh -DarchetypeArtifactId=jmh-java-benchmark-archetype -DgroupId=org.sample -DartifactId=test -Dversion=1.0

特別提醒:命令不要換行

3.啓動工程編寫測試代碼

將生成的代碼使用idea打開:

注意截圖中已將代碼拷貝到了其他地方

 編寫一個1+2+3.....+10億的測試代碼

比單線程與多線程的耗時

/*
 * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

package org.sample;

import org.openjdk.jmh.annotations.*;

import java.util.concurrent.FutureTask;

/**
 * 編寫一個1+2+3.....+10億的測試代碼
 * <p>
 * 比單線程與多線程的耗時
 */
@Fork(1)
@BenchmarkMode(Mode.AverageTime)
@Warmup(iterations = 3)
@Measurement(iterations = 5)
public class MyBenchmark {
    // 10億
    static int num = 1000_000_000;

    /**
     * 多線程計算
     *
     * @return
     * @throws Exception
     */
    @Benchmark
    public int testMethodMore() throws Exception {
        FutureTask<Integer> t1 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i < 250_000_000; i++) {
                sum += i;
            }
            return sum;
        });
        FutureTask<Integer> t2 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 250_000_000; i < 500_000_000; i++) {
                sum += i;
            }
            return sum;
        });
        FutureTask<Integer> t3 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 500_000_000; i < 750_000_000; i++) {
                sum += i;
            }
            return sum;
        });
        FutureTask<Integer> t4 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 750_000_000; i < 1000_000_000; i++) {
                sum += i;
            }
            return sum;
        });
        new Thread(t1).start();
        new Thread(t2).start();
        new Thread(t3).start();
        new Thread(t4).start();
        return t1.get() + t2.get() + t3.get() + t4.get();
    }

    /**
     * 普通循環計算
     *
     * @return
     * @throws Exception
     */
    @Benchmark
    public int testMethodSingle() throws Exception {
        FutureTask<Integer> t1 = new FutureTask<>(() -> {
            int sum = 0;
            for (int i = 0; i <= num; i++) {
                sum += i;
            }
            return sum;
        });
        new Thread(t1).start();
        return t1.get();
    }
}

 

4.打包與運行

打包:

 

 運行jar包:

 測試結果:

 可以明顯看到多線程比單線程快

 

提問:如果在單核CPU的情況下測試呢????? 

這個問題很值錢,這設計到你對併發、並行、多線程等核心概念的理解

 

測試完整日誌如下:

F:\JAVAEE高級課程體系\04_高級階段\java多線程-高級\code\test>java -jar target\benchmarks.jar
# VM invoker: D:\Program Files\Java\jre1.8.0_152\bin\java.exe
# VM options: <none>
# Warmup: 3 iterations, 1 s each
# Measurement: 5 iterations, 1 s each
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.testMethodMore

# Run progress: 0.00% complete, ETA 00:00:16
# Fork: 1 of 1
# Warmup Iteration   1: 0.130 s/op
# Warmup Iteration   2: 0.120 s/op
# Warmup Iteration   3: 0.115 s/op
Iteration   1: 0.125 s/op
Iteration   2: 0.118 s/op
Iteration   3: 0.126 s/op
Iteration   4: 0.114 s/op
Iteration   5: 0.122 s/op


Result: 0.121 ±(99.9%) 0.019 s/op [Average]
  Statistics: (min, avg, max) = (0.114, 0.121, 0.126), stdev = 0.005
  Confidence interval (99.9%): [0.102, 0.140]


# VM invoker: D:\Program Files\Java\jre1.8.0_152\bin\java.exe
# VM options: <none>
# Warmup: 3 iterations, 1 s each
# Measurement: 5 iterations, 1 s each
# Threads: 1 thread, will synchronize iterations
# Benchmark mode: Average time, time/op
# Benchmark: org.sample.MyBenchmark.testMethodSingle

# Run progress: 50.00% complete, ETA 00:00:10
# Fork: 1 of 1
# Warmup Iteration   1: 0.405 s/op
# Warmup Iteration   2: 0.381 s/op
# Warmup Iteration   3: 0.390 s/op
Iteration   1: 0.400 s/op
Iteration   2: 0.385 s/op
Iteration   3: 0.378 s/op
Iteration   4: 0.379 s/op
Iteration   5: 0.388 s/op


Result: 0.386 ±(99.9%) 0.033 s/op [Average]
  Statistics: (min, avg, max) = (0.378, 0.386, 0.400), stdev = 0.009
  Confidence interval (99.9%): [0.353, 0.419]


# Run complete. Total time: 00:00:21

Benchmark                           Mode  Samples  Score  Score error  Units
o.s.MyBenchmark.testMethodMore      avgt        5  0.121        0.019   s/op
o.s.MyBenchmark.testMethodSingle    avgt        5  0.386        0.033   s/op 

完美!

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