java jmh是什么,讓我們一起了解一下?
JMH是一種Java工具,用于構(gòu)建、運(yùn)行和分析用Java和其他針對(duì)JVM的語(yǔ)言編寫(xiě)的nano/micro/mili/macro基準(zhǔn)測(cè)試。JMH一般用于代碼的性能調(diào)優(yōu),精度可以達(dá)到納秒級(jí)別,適用于 java以及其他基于JVM的語(yǔ)言。
JMH注解說(shuō)明:
在運(yùn)行時(shí),注解配置被用于解析生成BenchmarkListEntry配置類(lèi)實(shí)例。
一個(gè)方法對(duì)應(yīng)一個(gè)@Benchmark注解,一個(gè)@Benchmark注解對(duì)應(yīng)一個(gè)基準(zhǔn)測(cè)試方法。
注釋在類(lèi)上的注解,或者注釋在類(lèi)的字段上的注解,則是類(lèi)中所有基準(zhǔn)測(cè)試方法共用的配置。
@Benchmark聲明一個(gè)public方法為基準(zhǔn)測(cè)試方法。
@BenchmarkMode通過(guò)JMH我們可以輕松的測(cè)試出某個(gè)接口的吞吐量、平均執(zhí)行時(shí)間等指標(biāo)的數(shù)據(jù)(假設(shè)我想測(cè)試testGson方法的平均耗時(shí),那么可以使用@BenchmarkMode注解指定測(cè)試維度為Mode.AverageTime。)
@Measurement測(cè)量次數(shù)
@Measurement假設(shè)我想測(cè)量testGson方法五次,那么可以使用@Measurement注解。
@Warmup配置預(yù)熱參數(shù)。
為了數(shù)據(jù)準(zhǔn)確,我們可能需要讓testGson方法做下熱身運(yùn)動(dòng)。如在方法中創(chuàng)建GsonParser對(duì)象,預(yù)熱可以避免首次創(chuàng)建GsonParser時(shí)因多了類(lèi)加載的耗時(shí)而導(dǎo)致測(cè)試結(jié)果不準(zhǔn)備的情況。jvm使用JIT即時(shí)編譯器,一定的預(yù)熱次數(shù)可讓JIT對(duì)testGson方法的調(diào)用鏈路完成編譯,去掉解釋執(zhí)行對(duì)測(cè)試結(jié)果的影響。
@OutputTimeUnit
OutputTimeUnit注解用于指定輸出的方法執(zhí)行耗時(shí)的單位。如果方法執(zhí)行耗時(shí)為秒級(jí)別,為了便于 觀察結(jié)果,我們可以使用@OutputTimeUnit指定輸出的耗時(shí)時(shí)間單位為秒;如果方法執(zhí)行耗時(shí)為毫秒級(jí)別,為了便于觀察結(jié)果,我們可以使用@OutputTimeUnit指定輸出的耗時(shí)時(shí)間單位為毫秒,否則使用默認(rèn)的秒做單位,會(huì)輸出10的負(fù)幾次方這樣的數(shù)字,不太直觀。
@Fork用于指定fork出多少個(gè)子進(jìn)程來(lái)執(zhí)行同一基準(zhǔn)測(cè)試方法。假設(shè)我們不需要多個(gè)進(jìn)程,那么 可以使用@Fork指定為進(jìn)程數(shù)為1。
@Threads注解用于指定使用多少個(gè)線程來(lái)執(zhí)行基準(zhǔn)測(cè)試方法,如果使用@Threads指定線程數(shù)為2,那么每次測(cè)量都會(huì)創(chuàng)建兩個(gè)線程來(lái)執(zhí)行基準(zhǔn)測(cè)試方法。
具體代碼如下:
public?void?lockInc(){ ????????lock.lock(); ????????try?{ ????????????x++; ????????}finally?{ ????????????lock.unlock(); ????????} ????} ??public??void?synInt(){ ??????synchronized?(this){ ??????????x++; ??????} ??} } @State(Scope.Group) public?static?class?InterMoticMonitor{ ????private?AtomicInteger?a=new?AtomicInteger(); ????public?void?atoMic(){ ????????a.incrementAndGet(); ????} } @Benchmark @Group("sync") @GroupThreads(10) public?void?syn(IntMonitor?intMonitor){ ????intMonitor.synInt(); } @Benchmark @Group("lock") @GroupThreads(10) public?void?lock(IntMonitor?intMonitor){ ????intMonitor.lockInc(); } @Benchmark @Group("Atomic") @GroupThreads(10) public?void?atominDemo(InterMoticMonitor?interMoticMonitor){ ????interMoticMonitor.atoMic(); } public?static?void?main(String[]?args)?throws?RunnerException?{ ????final?Options?opts=new?OptionsBuilder() ????????????.include(Explamlee01.class.getSimpleName()) ????????????.forks(1) ????????????.warmupIterations(10) ????????????.measurementIterations(10) ????????????.build(); ????new?Runner(opts).run(); }
以上就是小編今天的分享了,希望可以幫助到大家。