国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

橘子學(xué)JDK之JMH-02(BenchmarkModes)

這篇具有很好參考價(jià)值的文章主要介紹了橘子學(xué)JDK之JMH-02(BenchmarkModes)。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問。

一、案例二代碼

這次我們來搞一下官網(wǎng)文檔的第二個(gè)案例,我刪除了一些沒用的注釋,然后對(duì)代碼做了一下注釋的翻譯,可以看一下意思。

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {

    /*
     * Mode.Throughput, as stated in its Javadoc, measures the raw throughput by
     * continuously calling the benchmark method in a time-bound iteration, and
     * counting how many times we executed the method.
     *
     * We are using the special annotation to select the units to measure in,
     * although you can use the default.
     *
     * AI直譯:Mode.Throughput,如其Javadoc所述,通過在時(shí)間限制的迭代中連續(xù)調(diào)用基準(zhǔn)方法,
     * 并計(jì)算我們執(zhí)行該方法的次數(shù)來衡量原始吞吐量。我們正在使用特殊注解來選擇要測量的單位,盡管你可以使用默認(rèn)值。
     *
     * 我根據(jù)我的理解還是說幾句人話吧,他的意思是我們之前不是在案例1中輸出的是吞吐量的測試指標(biāo)嗎,這里的意思是你可以
     * 使用@BenchmarkMode這個(gè)注解,里面設(shè)置參數(shù)Mode.Throughput一樣可以是通過吞吐量的指標(biāo)的,或者說你不設(shè)置,默認(rèn)
     * 本身就是吞吐量,我們第一個(gè)案例就是默認(rèn)的。
     * 所以我們在第一個(gè)方法上看到新出現(xiàn)的兩個(gè)注解
     * @BenchmarkMode:設(shè)置計(jì)算指標(biāo)
     * @OutputTimeUnit:計(jì)算模式對(duì)應(yīng)的單位
     */

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.SECONDS)
    public void measureThroughput() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    /*
     * Mode.AverageTime measures the average execution time, and it does it
     * in the way similar to Mode.Throughput.
     * 在性能測試或基準(zhǔn)測試的背景下,Mode.AverageTime(平均時(shí)間模式)測量了給定操作或代碼片段的平均執(zhí)行時(shí)間。
     * 該模式計(jì)算了每次調(diào)用被測試代碼所花費(fèi)的平均時(shí)間。它與Mode.Throughput(吞吐量模式)相似,兩種模式都專注于性能測量,
     * 但它們在優(yōu)先考慮的性能方面存在差異。以下是Mode.AverageTime和Mode.Throughput之間的簡要比較:
     * 平均時(shí)間:該模式計(jì)算每個(gè)操作或調(diào)用的平均執(zhí)行時(shí)間。它提供了關(guān)于單個(gè)操作平均執(zhí)行時(shí)間的信息。
     * 吞吐量:另一方面,Mode.Throughput關(guān)注的是在給定時(shí)間內(nèi)完成的操作速率。它衡量每單位時(shí)間內(nèi)可以執(zhí)行多少操作,通常是每秒。
     * 它提供了系統(tǒng)在高負(fù)載下處理大量操作的效率信息。
     * 雖然兩種模式都提供了有關(guān)性能的有價(jià)值的信息,但它們服務(wù)于不同的目的,可能適用于不同類型的性能分析。
     * Mode.AverageTime適用于了解單個(gè)操作的平均延遲或執(zhí)行時(shí)間,而Mode.Throughput更適用于在指定時(shí)間范圍內(nèi)最大化完成的操作數(shù)量。
     *
     *
     * Some might say it is the reciprocal throughput, and it really is.
     * There are workloads where measuring times is more convenient though.
     * 有人說,這個(gè)指標(biāo)是吞吐量的倒數(shù),你也可以這么理解,不過有時(shí)候你測試的時(shí)候,統(tǒng)計(jì)時(shí)間維度是更加直觀的。
     *
     * 換言之,這個(gè)是統(tǒng)計(jì)你方法的執(zhí)行平均時(shí)間的,所以看起來比吞吐量更加直觀,畢竟耗時(shí)是我們普遍關(guān)心的第一指標(biāo)
     */
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureAvgTime() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    /*
     * Mode.SampleTime samples the execution time. With this mode, we are
     * still running the method in a time-bound iteration, but instead of
     * measuring the total time, we measure the time spent in *some* of
     * the benchmark method calls.
     *
     * Mode.SampleTime是用于對(duì)方法執(zhí)行時(shí)間進(jìn)行采樣的一種模式。在這種模式下,我們?nèi)匀辉谝粋€(gè)有時(shí)間限制的迭代中運(yùn)行方法,
     * 但不再測量總時(shí)間,而是測量一部分基準(zhǔn)方法調(diào)用所花費(fèi)的時(shí)間。使用Mode.SampleTime模式時(shí),
     * 基準(zhǔn)測試框架會(huì)定期中斷方法的執(zhí)行并記錄經(jīng)過的時(shí)間。通過只對(duì)部分調(diào)用進(jìn)行采樣,可以減少與連續(xù)時(shí)間測量相關(guān)的開銷,
     * 同時(shí)仍能提供有關(guān)方法執(zhí)行時(shí)間分布的有意義數(shù)據(jù),而不僅僅關(guān)注整體持續(xù)時(shí)間。這種模式對(duì)于識(shí)別執(zhí)行時(shí)間的變化非常有用,
     * 特別是如果方法的某些部分可能具有不同的性能特點(diǎn)或表現(xiàn)出間歇性行為。它使開發(fā)人員能夠了解方法在不同條件下的性能表現(xiàn),
     * 并幫助優(yōu)化其性能。
     *
     * This allows us to infer the distributions, percentiles, etc.
     * JMH also tries to auto-adjust sampling frequency: if the method
     * is long enough, you will end up capturing all the samples.
     * 這樣可以讓我們推斷出分布情況、百分位數(shù)等。JMH 還會(huì)嘗試自動(dòng)調(diào)整采樣頻率:如果方法足夠長,你最終會(huì)捕獲到所有的樣本
     *
     * 這個(gè)解釋的不明確,我們待會(huì)通過現(xiàn)象來看一下具體啥意思。
     */
    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureSamples() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    /*
     * Mode.SingleShotTime measures the single method invocation time. As the Javadoc
     * suggests, we do only the single benchmark method invocation. The iteration
     * time is meaningless in this mode: as soon as benchmark method stops, the
     * iteration is over.
     *
     * Mode.SingleShotTime測量的是單個(gè)方法調(diào)用的時(shí)間。正如Javadoc所建議的,我們只進(jìn)行一次基準(zhǔn)方法的調(diào)用。
     * 在這種模式下,迭代時(shí)間是沒有意義的:一旦基準(zhǔn)方法停止,迭代就結(jié)束了。
     *
     * This mode is useful to do cold startup tests, when you specifically
     * do not want to call the benchmark method continuously.
     * 這種模式在進(jìn)行冷啟動(dòng)測試時(shí)非常有用,當(dāng)你不想連續(xù)調(diào)用基準(zhǔn)方法時(shí)。
     *
     * 說白了就是只測試一次,就跟你跑main函數(shù)一樣的,沒有預(yù)熱,就是冷啟動(dòng)的測試。
     */
    @Benchmark
    @BenchmarkMode(Mode.SingleShotTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureSingleShot() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    /*
     * We can also ask for multiple benchmark modes at once. All the tests
     * above can be replaced with just a single test like this:
     *
     * 這個(gè)注解還能寫數(shù)組,指定多種測試指標(biāo),一起生效
     */
    @Benchmark
    @BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureMultiple() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    /*
     * Or even...
     * 如果你懶得寫很多模式,你還能直接用Mode.All來表示全部的模式
     */
    @Benchmark
    @BenchmarkMode(Mode.All)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureAll() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

二、@BenchmarkMode

我們先不急著運(yùn)行程序,我們在看完上面的例子之后可以看到這次出現(xiàn)了一個(gè)新的注解,就是
@BenchmarkMode

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface BenchmarkMode {
    Mode[] value();
}

這個(gè)注解我們看到,作用的位置就是方法和類上面,你要是標(biāo)注在類上,那就這個(gè)類所有的方法都按照這個(gè)配置生效了。
而且我們注意到他有一個(gè)變量,是Mode類型的數(shù)組,注意是數(shù)組,也就是可以傳入多個(gè)。我們看一下這個(gè)Mode類型是啥。

public enum Mode {
    Throughput("thrpt", "Throughput, ops/time"),
    AverageTime("avgt", "Average time, time/op"),
    SampleTime("sample", "Sampling time"),
    SingleShotTime("ss", "Single shot invocation time"),
    All("all", "All benchmark modes");
}

就是個(gè)枚舉類型,總共五個(gè)類型,我們上面的注釋其實(shí)也標(biāo)注了這五個(gè)類型的各自的作用。

三、 @OutputTimeUnit

與@BenchmarkMode 配套的還有一個(gè)注解就是@OutputTimeUnit。

@Inherited
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface OutputTimeUnit {
    TimeUnit value();
}

他的作用就是你輸出指標(biāo)的時(shí)間單位,沒別的了。OK,我們在大致有個(gè)了解之后,我們開始通過執(zhí)行程序來看一下結(jié)果,加深我們對(duì)于注解的理解。

四、執(zhí)行程序

鑒于我們這里這次一次寫了N個(gè)方法測試,輸出的報(bào)告巨長,我們這里就一個(gè)一個(gè)的測試,這樣方便觀察。

1、測試吞吐模式:measureThroughput

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {

    /*
     * Mode.Throughput, as stated in its Javadoc, measures the raw throughput by
     * continuously calling the benchmark method in a time-bound iteration, and
     * counting how many times we executed the method.
     *
     * We are using the special annotation to select the units to measure in,
     * although you can use the default.
     *
     * AI直譯:Mode.Throughput,如其Javadoc所述,通過在時(shí)間限制的迭代中連續(xù)調(diào)用基準(zhǔn)方法,
     * 并計(jì)算我們執(zhí)行該方法的次數(shù)來衡量原始吞吐量。我們正在使用特殊注解來選擇要測量的單位,盡管你可以使用默認(rèn)值。
     *
     * 我根據(jù)我的理解還是說幾句人話吧,他的意思是我們之前不是在案例1中輸出的是吞吐量的測試指標(biāo)嗎,這里的意思是你可以
     * 使用@BenchmarkMode這個(gè)注解,里面設(shè)置參數(shù)Mode.Throughput一樣可以是通過吞吐量的指標(biāo)的,或者說你不設(shè)置,默認(rèn)
     * 本身就是吞吐量,我們第一個(gè)案例就是默認(rèn)的。
     * 所以我們在第一個(gè)方法上看到新出現(xiàn)的兩個(gè)注解
     * @BenchmarkMode:設(shè)置計(jì)算指標(biāo)
     * @OutputTimeUnit:計(jì)算模式對(duì)應(yīng)的單位
     */

    @Benchmark
    @BenchmarkMode(Mode.Throughput)
    @OutputTimeUnit(TimeUnit.SECONDS)
    public void measureThroughput() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

運(yùn)行結(jié)果為:
Benchmark :JMHSample_02_01_BenchmarkModes.measureThroughput
Mode :thrpt
Cnt : 因?yàn)槲铱刂屏?次,所以這里沒東西
Score :9.160 這個(gè)分?jǐn)?shù)在吞吐這里其實(shí)就是你執(zhí)行的吞吐量,因?yàn)槲覍懙腀OutputTimeUnit(TimeUnit.SECONDS)單位是秒,所以意思就是一秒能執(zhí)行9.16次。
Error :沒輸出
Units:ops/s
我們看到這個(gè)吞吐量其實(shí)和我們在第一個(gè)案例測試的差不多,其實(shí)他就是默認(rèn)的。你不寫就是他。

2、測試平均時(shí)間模式:measureAvgTime

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {

   
    /*
     * Mode.AverageTime measures the average execution time, and it does it
     * in the way similar to Mode.Throughput.
     * 在性能測試或基準(zhǔn)測試的背景下,Mode.AverageTime(平均時(shí)間模式)測量了給定操作或代碼片段的平均執(zhí)行時(shí)間。
     * 該模式計(jì)算了每次調(diào)用被測試代碼所花費(fèi)的平均時(shí)間。它與Mode.Throughput(吞吐量模式)相似,兩種模式都專注于性能測量,
     * 但它們在優(yōu)先考慮的性能方面存在差異。以下是Mode.AverageTime和Mode.Throughput之間的簡要比較:
     * 平均時(shí)間:該模式計(jì)算每個(gè)操作或調(diào)用的平均執(zhí)行時(shí)間。它提供了關(guān)于單個(gè)操作平均執(zhí)行時(shí)間的信息。
     * 吞吐量:另一方面,Mode.Throughput關(guān)注的是在給定時(shí)間內(nèi)完成的操作速率。它衡量每單位時(shí)間內(nèi)可以執(zhí)行多少操作,通常是每秒。
     * 它提供了系統(tǒng)在高負(fù)載下處理大量操作的效率信息。
     * 雖然兩種模式都提供了有關(guān)性能的有價(jià)值的信息,但它們服務(wù)于不同的目的,可能適用于不同類型的性能分析。
     * Mode.AverageTime適用于了解單個(gè)操作的平均延遲或執(zhí)行時(shí)間,而Mode.Throughput更適用于在指定時(shí)間范圍內(nèi)最大化完成的操作數(shù)量。
     *
     *
     * Some might say it is the reciprocal throughput, and it really is.
     * There are workloads where measuring times is more convenient though.
     * 有人說,這個(gè)指標(biāo)是吞吐量的倒數(shù),你也可以這么理解,不過有時(shí)候你測試的時(shí)候,統(tǒng)計(jì)時(shí)間維度是更加直觀的。
     *
     * 換言之,這個(gè)是統(tǒng)計(jì)你方法的執(zhí)行平均時(shí)間的,所以看起來比吞吐量更加直觀,畢竟耗時(shí)是我們普遍關(guān)心的第一指標(biāo)
     */
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureAvgTime() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

運(yùn)行結(jié)果如下:
Benchmark :JMHSample_02_01_BenchmarkModes.measureAvgTime
Mode:avgt 平均統(tǒng)計(jì)模式
Cnt :同上
Score:108407.350
Error :沒錯(cuò)誤,不輸出
Units:us/op 其實(shí)你能看出來,他是時(shí)間除以執(zhí)行次數(shù),所以就是吞吐量的倒數(shù),吞吐量的意思是每秒能執(zhí)行幾次,這里就是執(zhí)行一次需要幾秒,不就是平均時(shí)間嗎。只是我指定的時(shí)間單位是@OutputTimeUnit(TimeUnit.MICROSECONDS)微秒,所以這里自然也就是這個(gè)單位。
他主打的是一個(gè)平均耗時(shí)。

3、測試統(tǒng)計(jì)時(shí)間:measureSamples

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {
    /*
     * Mode.SampleTime samples the execution time. With this mode, we are
     * still running the method in a time-bound iteration, but instead of
     * measuring the total time, we measure the time spent in *some* of
     * the benchmark method calls.
     *
     * Mode.SampleTime是用于對(duì)方法執(zhí)行時(shí)間進(jìn)行采樣的一種模式。在這種模式下,我們?nèi)匀辉谝粋€(gè)有時(shí)間限制的迭代中運(yùn)行方法,
     * 但不再測量總時(shí)間,而是測量一部分基準(zhǔn)方法調(diào)用所花費(fèi)的時(shí)間。使用Mode.SampleTime模式時(shí),
     * 基準(zhǔn)測試框架會(huì)定期中斷方法的執(zhí)行并記錄經(jīng)過的時(shí)間。通過只對(duì)部分調(diào)用進(jìn)行采樣,可以減少與連續(xù)時(shí)間測量相關(guān)的開銷,
     * 同時(shí)仍能提供有關(guān)方法執(zhí)行時(shí)間分布的有意義數(shù)據(jù),而不僅僅關(guān)注整體持續(xù)時(shí)間。這種模式對(duì)于識(shí)別執(zhí)行時(shí)間的變化非常有用,
     * 特別是如果方法的某些部分可能具有不同的性能特點(diǎn)或表現(xiàn)出間歇性行為。它使開發(fā)人員能夠了解方法在不同條件下的性能表現(xiàn),
     * 并幫助優(yōu)化其性能。
     *
     * This allows us to infer the distributions, percentiles, etc.
     * JMH also tries to auto-adjust sampling frequency: if the method
     * is long enough, you will end up capturing all the samples.
     * 這樣可以讓我們推斷出分布情況、百分位數(shù)等。JMH 還會(huì)嘗試自動(dòng)調(diào)整采樣頻率:如果方法足夠長,你最終會(huì)捕獲到所有的樣本
     *
     * 這個(gè)解釋的不明確,我們待會(huì)通過現(xiàn)象來看一下具體啥意思。
     */
    @Benchmark
    @BenchmarkMode(Mode.SampleTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureSamples() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

橘子學(xué)JDK之JMH-02(BenchmarkModes),# JDK,java
他是以一種分布統(tǒng)計(jì)的方式輸出的測試指標(biāo),單位還是平均時(shí)間耗時(shí),等于說百分之99的測試跑一次是109707.264us的耗時(shí),他內(nèi)部給你做了一個(gè)測試,拆分出來測的,測出這么個(gè)結(jié)果來。
能看出來一個(gè)波動(dòng),和你實(shí)現(xiàn)的代碼穩(wěn)定性,而且他是抽樣測試,不會(huì)都給你統(tǒng)計(jì),比如我們設(shè)置的跑1輪,每輪一秒??赡苓@一秒跑了一萬次,他不會(huì)像吞吐和平均那個(gè)樣都算進(jìn)去,他是一個(gè)抽樣,可能抽了前面后面,沒取中間??赡軌焊褪浅榱饲懊?。是一個(gè)分布統(tǒng)計(jì)。

4、測試只跑一次:measureSingleShot

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {
    /*
     * Mode.SingleShotTime measures the single method invocation time. As the Javadoc
     * suggests, we do only the single benchmark method invocation. The iteration
     * time is meaningless in this mode: as soon as benchmark method stops, the
     * iteration is over.
     *
     * Mode.SingleShotTime測量的是單個(gè)方法調(diào)用的時(shí)間。正如Javadoc所建議的,我們只進(jìn)行一次基準(zhǔn)方法的調(diào)用。
     * 在這種模式下,迭代時(shí)間是沒有意義的:一旦基準(zhǔn)方法停止,迭代就結(jié)束了。
     *
     * This mode is useful to do cold startup tests, when you specifically
     * do not want to call the benchmark method continuously.
     * 這種模式在進(jìn)行冷啟動(dòng)測試時(shí)非常有用,當(dāng)你不想連續(xù)調(diào)用基準(zhǔn)方法時(shí)。
     *
     * 說白了就是只測試一次,就跟你跑main函數(shù)一樣的,沒有預(yù)熱,就是冷啟動(dòng)的測試。
     */
    @Benchmark
    @BenchmarkMode(Mode.SingleShotTime)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureSingleShot() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

執(zhí)行結(jié)果如下:
橘子學(xué)JDK之JMH-02(BenchmarkModes),# JDK,java
這就是測試?yán)鋯?dòng)的,沒預(yù)熱,就是直接跑,你也能看到單位是us/op。還是執(zhí)行一次要多久。還是個(gè)平均值,只不過就是沒預(yù)熱直接開跑的。就跑一次。

5、測試多種模式組合:measureMultiple

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {

    /*
     * We can also ask for multiple benchmark modes at once. All the tests
     * above can be replaced with just a single test like this:
     *
     * 這個(gè)注解還能寫數(shù)組,指定多種測試指標(biāo),一起生效
     */
    @Benchmark
    @BenchmarkMode({Mode.Throughput, Mode.AverageTime, Mode.SampleTime, Mode.SingleShotTime})
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureMultiple() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }
    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

因?yàn)槲覀兦懊婵戳薓ode是一個(gè)數(shù)組,所以可以傳入多個(gè)模式。結(jié)果就是一起統(tǒng)計(jì)輸出了。
橘子學(xué)JDK之JMH-02(BenchmarkModes),# JDK,java

6、測試全量模式:measureAll

package com.levi;

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.concurrent.TimeUnit;

// 預(yù)熱注解,修改為只預(yù)熱一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Warmup(iterations = 1,time = 1)
// 測試執(zhí)行注解,修改為只執(zhí)行一輪,每輪只跑一秒,默認(rèn)是5,5這里改為1,1
@Measurement(iterations = 1,time = 1)
public class JMHSample_02_01_BenchmarkModes {
    /*
     * Or even...
     * 如果你懶得寫很多模式,你還能直接用Mode.All來表示全部的模式
     */
    @Benchmark
    @BenchmarkMode(Mode.All)
    @OutputTimeUnit(TimeUnit.MICROSECONDS)
    public void measureAll() throws InterruptedException {
        TimeUnit.MILLISECONDS.sleep(100);
    }

    public static void main(String[] args) throws RunnerException {
        Options opt = new OptionsBuilder()
                .include(JMHSample_02_01_BenchmarkModes.class.getSimpleName())
                .forks(1)
                .build();

        new Runner(opt).run();
    }
}

自然就是全部的統(tǒng)計(jì)都輸出了:和上面一樣。
橘子學(xué)JDK之JMH-02(BenchmarkModes),# JDK,java
你也可以看他的單位就知道他輸出的計(jì)算方式了,次數(shù)除以時(shí)間,那就是平均時(shí)間的執(zhí)行次數(shù),就是吞吐。
時(shí)間除以次數(shù),就是統(tǒng)計(jì)的某種模式下的平均時(shí)間。

五、總結(jié)

沒啥總結(jié)的就是那兩個(gè)注解,很詳細(xì)了。

六、參考鏈接

1、JMH官方文檔文章來源地址http://www.zghlxwxcb.cn/news/detail-852948.html

到了這里,關(guān)于橘子學(xué)JDK之JMH-02(BenchmarkModes)的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • JMH - Java代碼基準(zhǔn)測試工具,代碼性能問題驗(yàn)證測試

    在日常開發(fā)工作當(dāng)中,開發(fā)人員可能有這些困惑:自己寫的這個(gè)方法性能到底怎么樣?在原接口實(shí)現(xiàn)方法中添加了新的業(yè)務(wù)邏輯,對(duì)整個(gè)接口的性能影響有多少?有多種實(shí)現(xiàn)方式(或開源類庫),到底哪一種性能更好? 當(dāng)遇到類似困惑或者說問題的時(shí)候,怎么辦呢?當(dāng)然是測試

    2024年02月07日
    瀏覽(23)
  • Linux02(項(xiàng)目部署,手動(dòng)和自動(dòng)部署,JDK版本問題,安裝軟件,安裝軟件,安裝JDK,Tomcat,MySQL,Irzsz)

    Linux02(項(xiàng)目部署,手動(dòng)和自動(dòng)部署,JDK版本問題,安裝軟件,安裝軟件,安裝JDK,Tomcat,MySQL,Irzsz)

    目錄 一、安裝軟件 1. 安裝準(zhǔn)備工作 1 Linux里的軟件安裝方式 2 上傳軟件到Linux 3 拍照虛擬機(jī)快照 2. 安裝JDK 1 卸載自帶jdk 2 解壓JDK 3 配置環(huán)境變量 4 測試JDK 3. 安裝Tomcat 1 解壓Tomcat 2 修改防火墻設(shè)置 3 測試Tomcat 啟動(dòng)Tomcat 訪問Tomcat 查看Tomcat日志 4 關(guān)閉Tomcat 4. 安裝MySQL 1 卸載自帶

    2024年04月18日
    瀏覽(31)
  • Ubuntu22.04 Hadoop3.3.4 jdk18.02 安裝配置

    Ubuntu22.04 Hadoop3.3.4 jdk18.02 安裝配置

    閱讀推薦(105條消息) 大數(shù)據(jù)安裝之hadoop-3.3.4_x_y_z423的博客-CSDN博客 (112條消息) hadoop3.3.4集群安裝部署_hwbays的博客-CSDN博客 加倍推薦,Hadoop集群配置內(nèi)容講的及其詳細(xì) 基于docker的hadoop集群搭建 xshell Windows 10 Pro, 64-bit VMware? Workstation 16 Pro Ubuntu22.04 * 3 2、VMware tools安裝 apt install

    2023年04月11日
    瀏覽(30)
  • 測試工具之JMH詳解

    測試工具之JMH詳解

    在日常開發(fā)中,我們對(duì)一些代碼的調(diào)用或者工具的使用會(huì)存在多種選擇方式,在不確定他們性能的時(shí)候,我們首先想要做的就是去測量它。大多數(shù)時(shí)候,我們會(huì)簡單的采用多次計(jì)數(shù)的方式來測量,來看這個(gè)方法的總耗時(shí)。 但是,如果熟悉 JVM 類加載機(jī)制的話,應(yīng)該知道 JVM 默

    2024年02月08日
    瀏覽(24)
  • 【精通性能優(yōu)化:解鎖JMH微基準(zhǔn)測試】一基本用法

    1. 什么是JMH JMH是Java Micro Benchmark Harness的簡寫,是專門用于代碼微基準(zhǔn)測試的工具集。 JMH由實(shí)現(xiàn)Java虛擬你的團(tuán)隊(duì)開發(fā),現(xiàn)代JVM已經(jīng)變的越來越智能,在Java文件的編譯階段、類的加載階段,以及運(yùn)行階段都可能進(jìn)行了不同程度的優(yōu)化,因此開發(fā)者編寫的代碼未必會(huì)像自己所預(yù)

    2024年02月12日
    瀏覽(18)
  • 【LeetCode-中等題】994. 腐爛的橘子

    【LeetCode-中等題】994. 腐爛的橘子

    該題值推薦用bfs,因?yàn)槭且粚右粚拥母腥?,而不是一條線走到底的那種,所以深度優(yōu)先搜索不適合 廣度優(yōu)先搜索,就是從起點(diǎn)出發(fā),每次都嘗試訪問同一層的節(jié)點(diǎn),如果同一層都訪問完了,再訪問下一層,最后廣度優(yōu)先搜索找到的路徑就是從起點(diǎn)開始的最短合法路徑。 在該

    2024年02月10日
    瀏覽(17)
  • 【LeetCode熱題100】【圖論】腐爛的橘子

    題目描述:994. 腐爛的橘子 - 力扣(LeetCode) 腐爛的橘子會(huì)污染周圍的橘子,要求多少輪擴(kuò)散才能把全部橘子污染,這就相當(dāng)于滴墨水入清水,會(huì)擴(kuò)散,其實(shí)就是廣度遍歷,看看遍歷多少層可以遍歷完可以遍歷的 先遍歷一次橘子,記錄下腐爛橘子的位置和新鮮橘子的數(shù)目,然

    2024年04月23日
    瀏覽(13)
  • 【圖論】Leetcode 994. 腐爛的橘子【中等】

    【圖論】Leetcode 994. 腐爛的橘子【中等】

    在給定的 m x n 網(wǎng)格 grid 中,每個(gè)單元格可以有以下三個(gè)值之一: 值 0 代表空單元格; 值 1 代表新鮮橘子; 值 2 代表腐爛的橘子。 每分鐘,腐爛的橘子 周圍 4 個(gè)方向上相鄰 的新鮮橘子都會(huì)腐爛。 返回 直到單元格中沒有新鮮橘子為止所必須經(jīng)過的最小分鐘數(shù)。如果不可能,

    2024年04月15日
    瀏覽(20)
  • 【leetcode994】腐爛的橘子(BFS)

    【leetcode994】腐爛的橘子(BFS)

    首先將所有爛橘子入隊(duì),然后常規(guī)BFS遍歷,注意 while 的截止條件除了隊(duì)列為空, 新鮮橘子數(shù)量大于0 (沒新鮮橘子也沒必要繼續(xù)遍歷,保證時(shí)間計(jì)算的正確性),這兩者一個(gè)不滿足就可以停止 每分鐘進(jìn)行一次【腐爛擴(kuò)散】,使用BFS對(duì)二維圖進(jìn)行遍歷,注意和二叉樹的層次遍

    2024年02月19日
    瀏覽(15)
  • 這個(gè)AI模型能識(shí)別出這個(gè)橘子嗎?

    這個(gè)AI模型能識(shí)別出這個(gè)橘子嗎?

    ??主頁 Nowl ??專欄 《AI模型分享》 ??君子坐而論道,少年起而行之 ?? 圖像識(shí)別任務(wù)是人工智能計(jì)算機(jī)視覺領(lǐng)域一個(gè)重要的子任務(wù),本篇文章將通過使用一個(gè)預(yù)訓(xùn)練模型來幫助讀者快速上手圖像識(shí)別任務(wù),對(duì)應(yīng)的文件可通過關(guān)注文章末尾的公眾號(hào)領(lǐng)取 本篇文章需要一定

    2024年02月03日
    瀏覽(15)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包