引言
? ? ? ? JMH是OpenJDK的JIT團(tuán)隊(duì)開發(fā)的微基準(zhǔn)測(cè)試框架,可針對(duì)基準(zhǔn)方法在吞吐量、響應(yīng)時(shí)間等維度進(jìn)行納秒/微秒/毫秒/秒級(jí)的性能基準(zhǔn)測(cè)試。隨著虛擬機(jī)的逐步優(yōu)化,過(guò)去的一些常見說(shuō)辭已經(jīng)不再那么絕對(duì),比如:final 修飾的變量性能更好,對(duì)象使用后賦null可以加快GC回收等。因此性能的好壞需要量化比較,JMH正是解決這方面的好工具。
JMH典型應(yīng)用場(chǎng)景
? ? ? ? 1、直觀比較兩個(gè)函數(shù)的性能高低
? ? ? ? 2、統(tǒng)計(jì)單位時(shí)間接口的吞吐量
? ? ? ? 3、統(tǒng)計(jì)規(guī)定周期內(nèi)函數(shù)的平均執(zhí)行時(shí)間,計(jì)算函數(shù)執(zhí)行時(shí)間與輸入規(guī)模的關(guān)聯(lián)性等
JMH執(zhí)行方式:
? ? ? ? 1、通過(guò)Maven搭建微基準(zhǔn)測(cè)試項(xiàng)目,打包項(xiàng)目為.jar的形式執(zhí)行。(官方推薦做法,測(cè)試結(jié)果更準(zhǔn)確、可靠)

? ? ? ? 2、在Eclipse環(huán)境項(xiàng)目中引入JMH依賴的插件及jar包,以Main方式執(zhí)行步驟如下。
? ? ? ? a、設(shè)置依賴


? ? ? ? b、安裝插件,啟用maven項(xiàng)目對(duì)注解的支持


樣例1:對(duì)比各種字符串拼接方式,每秒的吞吐量

代碼實(shí)現(xiàn),詳見https://github.com/SolodanceMagicq/algorithm_practice/blob/master/src/algo/java/jmh/StringOpt.java
小結(jié):
? ? ? ? 由基準(zhǔn)測(cè)試結(jié)果可見,性能由高到低為 :+拼接常量字符串 >StringBuilder>StringBuffer>同步修飾StringBuilder>+拼接變量字符串。
????????JIT團(tuán)隊(duì)對(duì)常量拼接進(jìn)行了優(yōu)化,+拼接常量字符串的性能最高;其次是StringBuilder,由于構(gòu)建的字符串對(duì)象少,且無(wú)同步鎖,性能次之;StringBuffer比StringBuilder稍差一些,由兩者的原碼可見,主要差在鎖同步操作上了;+拼接變量字符串,會(huì)創(chuàng)建大量StringBuilder中間對(duì)象,性能最差;而鎖同步的StringBuilder性能比StringBuilder性能差距較大,可見我們當(dāng)前一個(gè)線程情況下,不涉及到并發(fā)訪問(wèn),JVM并沒有將不必要的鎖同步優(yōu)化掉。即便相同的代碼用不用鎖,性能影響也很大。(PS :之前網(wǎng)上總說(shuō),非多線程場(chǎng)景下,JVM會(huì)進(jìn)行鎖優(yōu)化,去掉不必要的同步操作,使之與不使用synchronized關(guān)鍵字一樣,至少這個(gè)基準(zhǔn)測(cè)試結(jié)果并沒反饋?;蛟S我的這個(gè)用例沒達(dá)到JVM優(yōu)化條件吧?)
樣例2:對(duì)數(shù)組、ArrayList和LinkedList集合的各種迭代方式進(jìn)行吞吐量對(duì)比測(cè)試

代碼實(shí)現(xiàn),詳見https://github.com/SolodanceMagicq/algorithm_practice/blob/master/src/algo/java/jmh/CollectorOpt.java
小結(jié):從測(cè)試結(jié)果反饋,Array和基于數(shù)組的集合采用下標(biāo)迭代的性能最高。鏈表迭代的性能普遍不高。(引申 :使用Iterator進(jìn)行迭代過(guò)程中可以對(duì)元素進(jìn)行添加、刪除操作,而增強(qiáng)for循環(huán)則不可以,會(huì)發(fā)生fast-fail,阿里規(guī)約中規(guī)定禁止在增強(qiáng)for循環(huán)過(guò)程中進(jìn)行對(duì)集合做元素個(gè)數(shù)變更操作。)
參考:
http://openjdk.java.net/projects/code-tools/jmh/
http://tutorials.jenkov.com/java-performance/jmh.html#writing-good-benchmarks
? ??????