引言
? ? ? ? JMH是OpenJDK的JIT團(tuán)隊開發(fā)的微基準(zhǔn)測試框架彤枢,可針對基準(zhǔn)方法在吞吐量碳想、響應(yīng)時間等維度進(jìn)行納秒/微秒/毫秒/秒級的性能基準(zhǔn)測試。隨著虛擬機的逐步優(yōu)化凸郑,過去的一些常見說辭已經(jīng)不再那么絕對驹暑,比如:final 修飾的變量性能更好曙蒸,對象使用后賦null可以加快GC回收等捌治。因此性能的好壞需要量化比較,JMH正是解決這方面的好工具纽窟。
JMH典型應(yīng)用場景
? ? ? ? 1肖油、直觀比較兩個函數(shù)的性能高低
? ? ? ? 2、統(tǒng)計單位時間接口的吞吐量
? ? ? ? 3臂港、統(tǒng)計規(guī)定周期內(nèi)函數(shù)的平均執(zhí)行時間森枪,計算函數(shù)執(zhí)行時間與輸入規(guī)模的關(guān)聯(lián)性等
JMH執(zhí)行方式:
? ? ? ? 1、通過Maven搭建微基準(zhǔn)測試項目审孽,打包項目為.jar的形式執(zhí)行县袱。(官方推薦做法,測試結(jié)果更準(zhǔn)確佑力、可靠)
? ? ? ? 2式散、在Eclipse環(huán)境項目中引入JMH依賴的插件及jar包,以Main方式執(zhí)行步驟如下打颤。
? ? ? ? a暴拄、設(shè)置依賴
? ? ? ? b、安裝插件编饺,啟用maven項目對注解的支持
樣例1:對比各種字符串拼接方式乖篷,每秒的吞吐量
代碼實現(xiàn),詳見https://github.com/SolodanceMagicq/algorithm_practice/blob/master/src/algo/java/jmh/StringOpt.java
小結(jié):
? ? ? ? 由基準(zhǔn)測試結(jié)果可見透且,性能由高到低為 :+拼接常量字符串 >StringBuilder>StringBuffer>同步修飾StringBuilder>+拼接變量字符串撕蔼。
????????JIT團(tuán)隊對常量拼接進(jìn)行了優(yōu)化,+拼接常量字符串的性能最高秽誊;其次是StringBuilder鲸沮,由于構(gòu)建的字符串對象少,且無同步鎖锅论,性能次之诉探;StringBuffer比StringBuilder稍差一些,由兩者的原碼可見棍厌,主要差在鎖同步操作上了;+拼接變量字符串竖席,會創(chuàng)建大量StringBuilder中間對象耘纱,性能最差;而鎖同步的StringBuilder性能比StringBuilder性能差距較大毕荐,可見我們當(dāng)前一個線程情況下束析,不涉及到并發(fā)訪問,JVM并沒有將不必要的鎖同步優(yōu)化掉憎亚。即便相同的代碼用不用鎖员寇,性能影響也很大弄慰。(PS :之前網(wǎng)上總說,非多線程場景下蝶锋,JVM會進(jìn)行鎖優(yōu)化陆爽,去掉不必要的同步操作,使之與不使用synchronized關(guān)鍵字一樣扳缕,至少這個基準(zhǔn)測試結(jié)果并沒反饋慌闭。或許我的這個用例沒達(dá)到JVM優(yōu)化條件吧躯舔?)
樣例2:對數(shù)組驴剔、ArrayList和LinkedList集合的各種迭代方式進(jìn)行吞吐量對比測試
代碼實現(xiàn),詳見https://github.com/SolodanceMagicq/algorithm_practice/blob/master/src/algo/java/jmh/CollectorOpt.java
小結(jié):從測試結(jié)果反饋粥庄,Array和基于數(shù)組的集合采用下標(biāo)迭代的性能最高丧失。鏈表迭代的性能普遍不高。(引申 :使用Iterator進(jìn)行迭代過程中可以對元素進(jìn)行添加惜互、刪除操作布讹,而增強for循環(huán)則不可以,會發(fā)生fast-fail载佳,阿里規(guī)約中規(guī)定禁止在增強for循環(huán)過程中進(jìn)行對集合做元素個數(shù)變更操作炒事。)
參考:
http://openjdk.java.net/projects/code-tools/jmh/
http://tutorials.jenkov.com/java-performance/jmh.html#writing-good-benchmarks
? ??????