一个简单的Map Iterator性能测试
Java Map性能有很多方面可以衡量,但是關(guān)鍵的一個(gè)是簡(jiǎn)單的單線程掃描。 這是一些針對(duì)Iterators和Java 8 Map.forEach()簡(jiǎn)單測(cè)試代碼,以及一些圖形結(jié)果。
1.性能測(cè)試?yán)щy
性能測(cè)試是一項(xiàng)非常困難的工作,精確的可重復(fù)測(cè)試需要Java微基準(zhǔn)測(cè)試線束之類(lèi)的框架來(lái)過(guò)濾掉許多噪聲源并提供諸如置信區(qū)間之類(lèi)的統(tǒng)計(jì)信息。 但是,這里簡(jiǎn)單測(cè)試代碼的結(jié)果是相對(duì)可重復(fù)的,并且與作者在JDK Maps和AirConcurrentMap(在boilerbay.com和githuboilbay / airconcurrentmap )上進(jìn)行的JMH測(cè)試很好地相關(guān)。 還有針對(duì)流等的更廣泛的JMH測(cè)試。
JMH并不復(fù)雜,但是它需要將工具從IDE切換到Maven模型,學(xué)習(xí)控件注釋集,并處理充滿麻煩的另一個(gè)目錄樹(shù)以及可能的新IDE項(xiàng)目。 另外,我們希望一次運(yùn)行即可自動(dòng)跨越一系列地圖大小和一組地圖:這需要JMH中的“參數(shù)化”注釋。 該測(cè)試的輸出數(shù)據(jù)格式可以輕松調(diào)整,以符合所需繪圖工具的需求。
1.1引起噪音的問(wèn)題
要獲得良好的測(cè)試,必須解決許多問(wèn)題:
2.結(jié)果
這些預(yù)防措施有助于我們得出一些初步但可重復(fù)的結(jié)論。 結(jié)果顯示:
- forEach()比Iterators快得多;
- 在大約3萬(wàn)個(gè)條目以下,ConcurrentSkipListMap的迭代速度最快,而在上面,AirConcurrentMap的迭代速度最快;
- ConcurrentSkipListMap forEach()在大約100個(gè)條目以下最快,而AirConcurrentMap在上面最快。
3.代碼詳細(xì)信息
測(cè)試代碼使用Test類(lèi)包裝器來(lái)包含特定的Map以及測(cè)試進(jìn)度狀態(tài),例如時(shí)間,map大小,循環(huán)和運(yùn)行總計(jì)。 該組織希望使main()更具可讀性。
Test類(lèi)實(shí)現(xiàn)BiConsumer以便可以在forEach(this)調(diào)用中使用它。 它只是覆蓋了accept(Integer, Integer) 。 我們還測(cè)試了forEach((k, v) -> total += v) (作者嘗試過(guò),結(jié)果大致相同)。 無(wú)論哪種情況,都不能將局部變量用作總累加器,因?yàn)榫植孔兞勘仨殹坝行У亍苯K止于內(nèi)部類(lèi)或lambda,因此無(wú)論如何我們都需要一個(gè)包含范圍的實(shí)例變量,例如Test那個(gè)。 使用流進(jìn)行簡(jiǎn)化也可以,但是我們對(duì)Iterators感興趣。 (有關(guān)/ jmh中的相關(guān)流測(cè)試,請(qǐng)參見(jiàn)https://github.com/boilerbay/airconcurrentmap )。
心跳是一個(gè)static int ,每秒由一個(gè)單獨(dú)的Thread遞增一次。 心跳必須是易失的,以便其更改在線程之間傳播–否則程序永遠(yuǎn)不會(huì)終止。
USE_ITERATION和USE_LAMBDA標(biāo)志是static final ,因此javac實(shí)際上會(huì)提前評(píng)估它影響的代碼,從而USE_LAMBDA代碼。 這被定義為必需的行為,因此那里沒(méi)有開(kāi)銷(xiāo)。 當(dāng)然,您必須重新編譯才能進(jìn)行各種測(cè)試,只是不要將它們更改為非靜態(tài)或非最終的!
test.testIterator()的動(dòng)態(tài)方法調(diào)用不會(huì)減慢內(nèi)部循環(huán)的速度,因?yàn)榭偸莾?nèi)聯(lián)長(zhǎng)度為35個(gè)字節(jié)或更少的方法。 而且,這里沒(méi)有多態(tài)性Test類(lèi)沒(méi)有擴(kuò)展,因此沒(méi)有用于分發(fā)的vtable,也沒(méi)有要壓入堆棧的參數(shù)。
測(cè)試是相對(duì)可重復(fù)的,并在圖中顯示了總體模式。
4.代碼
public class JavaCodeGeeksIteratorArticle {static volatile int heartBeat = 0;// otherwise use forEach()static final boolean USE_ITERATION = false;static final boolean USE_LAMBDA = true;public static void main(String... args) {System.out.println((USE_ITERATION ? "Iterator" :USE_LAMBDA ? " forEach(lambda)" : "ForEach()") + " performance test");Test tests[] = {new Test(new HashMap<Integer, Integer>()),new Test(new TreeMap<Integer, Integer>()),new Test(new ConcurrentHashMap<Integer, Integer>()),new Test(new ConcurrentSkipListMap<Integer, Integer>()),new Test(new AirConcurrentMap<Integer, Integer>())};int sizes[] = new int[] {1, 3, 10, 30, 100, 300, 1000, 3000, 10_000, 30_000, 100_000, 300_000,1000_000, 3_000_000, 10_000_000};// Just increment heartBeat every so often. It is volatile.// Reading it is very fast.new Thread(new Runnable() {public void run() {while (true) {heartBeat++;try {Thread.sleep(100);} catch (InterruptedException e) {}}}}).start();for (int i = 0; i < sizes.length; i++) {for (Test test : tests)test.fillTo(sizes[i]);// warmupfor (Test test : tests) {int nextHeartBeat = heartBeat + 20;while (heartBeat < nextHeartBeat)if (USE_ITERATION)test.testIterator();else if (USE_LAMBDA)test.testForEachLambda();elsetest.testForEach();}for (Test test : tests) {test.time = 0;test.loops = 0;long t0 = System.nanoTime();int nextHeartBeat = heartBeat + 30;while (heartBeat < nextHeartBeat) {if (USE_ITERATION)test.testIterator();else if (USE_LAMBDA)test.testForEachLambda();elsetest.testForEach();}long t1 = System.nanoTime();test.time += (t1 - t0);}for (Test test : tests)test.printResult();// System.out.println("---------------");}} }class Test implements BiConsumer<Integer, Integer> {// The total provides a tangible result to prevent optimizing-outlong total = 0;long time = 0;int size = 0;long loops = 1;Map<Integer, Integer> map;Test(Map<Integer, Integer> map) {this.map = map;}void fillTo(int newSize) {Random random = new Random(size);while (size < newSize) {Integer n = new Integer(random.nextInt()); map.put(n, n); size++;}}void testIterator() { for (Integer v : map.values()) {total += v.intValue(); } loops++; }// This has the same effect and is 'terser' void testForEachLambda() {map.forEach((k, v) -> total += v);loops++;}void testForEach() {map.forEach(this);loops++;}// Implement BiConsumer for forEach()@Overridepublic void accept(Integer k, Integer v) {total += k.intValue();}void printResult() {double seconds = time / 1e9;System.out.printf("%22s size=% 9d entries/s(K)=% 11.3f total=%d\n",map.getClass().getSimpleName(), size, size * loops / seconds / 1e3, total);} }5.結(jié)果數(shù)據(jù)
圖表數(shù)據(jù)如下。 例如,可以將其導(dǎo)入Excel并按Map類(lèi)和大小進(jìn)行排序以手動(dòng)制作圖形。 您需要剪切并粘貼數(shù)據(jù),然后使用文本到列。 可以使用折線圖,為每個(gè)Map類(lèi)手動(dòng)選擇一個(gè)系列數(shù)據(jù)。 通過(guò)更改數(shù)據(jù)輸出格式,也可以使用“ R”統(tǒng)計(jì)語(yǔ)言的ggplot。 忽略總數(shù):這僅提供了有形輸出,以避免優(yōu)化循環(huán)。
JavaCodeGeeksIteratorArticleIterator performance testHashMap size= 1 entries/s= 31290.754K total=-289049400605539520TreeMap size= 1 entries/s= 50210.333K total=-331631386373881504ConcurrentHashMap size= 1 entries/s= 15881.356K total=-91464608232057952ConcurrentSkipListMap size= 1 entries/s= 42187.535K total=-254234286353018080AirConcurrentMap size= 1 entries/s= 25577.125K total=-149805405784208032 ---------------HashMap size= 3 entries/s= 62664.626K total=-484691989675689270TreeMap size= 3 entries/s= 66908.091K total=-550745245141063704ConcurrentHashMap size= 3 entries/s= 38018.996K total=-211326922860746827ConcurrentSkipListMap size= 3 entries/s= 71265.063K total=-488278692474832005AirConcurrentMap size= 3 entries/s= 48540.146K total=-302163579336545082 ---------------HashMap size= 10 entries/s= 86701.181K total=-832795481348512598TreeMap size= 10 entries/s= 87832.407K total=-916137658370092344ConcurrentHashMap size= 10 entries/s= 73069.458K total=-502840045890573499ConcurrentSkipListMap size= 10 entries/s= 96150.046K total=-880874881700377401AirConcurrentMap size= 10 entries/s= 72001.056K total=-591224549191451578 ---------------HashMap size= 30 entries/s= 89419.363K total=-832238604657166224TreeMap size= 30 entries/s= 92397.645K total=-915559545928720920ConcurrentHashMap size= 30 entries/s= 71702.258K total=-502393457157098057ConcurrentSkipListMap size= 30 entries/s= 103387.524K total=-880213560719307683AirConcurrentMap size= 30 entries/s= 80807.271K total=-590716865563759348 ---------------HashMap size= 100 entries/s= 90540.307K total=-845663104709828079TreeMap size= 100 entries/s= 96479.776K total=-930300717715488858ConcurrentHashMap size= 100 entries/s= 69055.433K total=-512752383626539310ConcurrentSkipListMap size= 100 entries/s= 111208.365K total=-897628029635465726AirConcurrentMap size= 100 entries/s= 89071.481K total=-604453907970584431 ---------------HashMap size= 300 entries/s= 94846.852K total=-860347586557330269TreeMap size= 300 entries/s= 94506.995K total=-944821983122037883ConcurrentHashMap size= 300 entries/s= 65857.587K total=-522786710141245214ConcurrentSkipListMap size= 300 entries/s= 112398.344K total=-915694233970137252AirConcurrentMap size= 300 entries/s= 92168.052K total=-618862268508225735 ---------------HashMap size= 1000 entries/s= 74493.997K total=-852961390806337305TreeMap size= 1000 entries/s= 80026.348K total=-937067262358689631ConcurrentHashMap size= 1000 entries/s= 38450.309K total=-519070765727723030ConcurrentSkipListMap size= 1000 entries/s= 112085.413K total=-904572392174355552AirConcurrentMap size= 1000 entries/s= 89022.852K total=-609589031935380951 ---------------HashMap size= 3000 entries/s= 57470.417K total=-847037038798366713TreeMap size= 3000 entries/s= 65963.172K total=-930168324830420495ConcurrentHashMap size= 3000 entries/s= 41073.089K total=-514814334734654678ConcurrentSkipListMap size= 3000 entries/s= 109217.866K total=-892841347702876464AirConcurrentMap size= 3000 entries/s= 89175.845K total=-600361285087522951 ---------------HashMap size= 10000 entries/s= 46254.558K total=-846309210319384299TreeMap size= 10000 entries/s= 49044.408K total=-929403633977808893ConcurrentHashMap size= 10000 entries/s= 36385.473K total=-514246034592481772ConcurrentSkipListMap size= 10000 entries/s= 99442.425K total=-891342788950136070AirConcurrentMap size= 10000 entries/s= 85447.544K total=-599022098209904335 ---------------HashMap size= 30000 entries/s= 43723.556K total=-848942181585517584TreeMap size= 30000 entries/s= 45253.915K total=-932143497084889069ConcurrentHashMap size= 30000 entries/s= 32665.051K total=-516220137420939070ConcurrentSkipListMap size= 30000 entries/s= 83393.494K total=-896231928805619954AirConcurrentMap size= 30000 entries/s= 80619.262K total=-603845100973163554 ---------------HashMap size= 100000 entries/s= 40028.088K total=-849706795555554639TreeMap size= 100000 entries/s= 41755.506K total=-932944794183923404ConcurrentHashMap size= 100000 entries/s= 26064.027K total=-516724530444651670ConcurrentSkipListMap size= 100000 entries/s= 46619.667K total=-897138307784594414AirConcurrentMap size= 100000 entries/s= 75034.058K total=-605290263409285564 ---------------HashMap size= 300000 entries/s= 28271.140K total=-850157323063101369TreeMap size= 300000 entries/s= 23442.635K total=-933312552546033574ConcurrentHashMap size= 300000 entries/s= 22886.588K total=-517086645455936620ConcurrentSkipListMap size= 300000 entries/s= 26852.530K total=-897567202447311134AirConcurrentMap size= 300000 entries/s= 43406.800K total=-605991920028554584 ---------------HashMap size= 1000000 entries/s= 20762.874K total=-850266118577777400TreeMap size= 1000000 entries/s= 21465.730K total=-933426629396373490ConcurrentHashMap size= 1000000 entries/s= 17617.501K total=-517179596963620996ConcurrentSkipListMap size= 1000000 entries/s= 17753.452K total=-897660153954995510AirConcurrentMap size= 1000000 entries/s= 24726.115K total=-606121840885886155 ---------------HashMap size= 3000000 entries/s= 20859.307K total=-850290350569160265TreeMap size= 3000000 entries/s= 17078.422K total=-933446707332090721ConcurrentHashMap size= 3000000 entries/s= 19987.888K total=-517202444269781983ConcurrentSkipListMap size= 3000000 entries/s= 23990.479K total=-897687847659433070AirConcurrentMap size= 3000000 entries/s= 30472.006K total=-606157150359044044 ---------------HashMap size= 10000000 entries/s= 18594.336K total=-850335966429011695TreeMap size= 10000000 entries/s= 14332.011K total=-933483200019971865ConcurrentHashMap size= 10000000 entries/s= 17038.665K total=-517248060129633413ConcurrentSkipListMap size= 10000000 entries/s= 18600.417K total=-897733463519284500AirConcurrentMap size= 10000000 entries/s= 39037.289K total=-606248382078746904 ---------------ForEach() performance testHashMap size= 1 entries/s= 60469.332K total=-429010055848020608TreeMap size= 1 entries/s= 162720.446K total=-1192873323002853184ConcurrentHashMap size= 1 entries/s= 39683.288K total=-238381128098095008ConcurrentSkipListMap size= 1 entries/s= 125216.579K total=-742139402594604448AirConcurrentMap size= 1 entries/s= 40199.780K total=-223453462147226592 ---------------HashMap size= 3 entries/s= 154792.076K total=-907351702836558858TreeMap size= 3 entries/s= 209809.380K total=-1866688472587176884ConcurrentHashMap size= 3 entries/s= 100788.166K total=-558021636792810008ConcurrentSkipListMap size= 3 entries/s= 202179.445K total=-1380005440196857173AirConcurrentMap size= 3 entries/s= 99654.211K total=-536118642462089017 ---------------HashMap size= 10 entries/s= 297297.392K total=-2080956150412338142TreeMap size= 10 entries/s= 228262.234K total=-2782965758065995472ConcurrentHashMap size= 10 entries/s= 189641.651K total=-1313404093180619596ConcurrentSkipListMap size= 10 entries/s= 304427.266K total=-2602702896415550485AirConcurrentMap size= 10 entries/s= 179131.091K total=-1257952993772621945 ---------------HashMap size= 30 entries/s= 305634.315K total=-2079066757218703314TreeMap size= 30 entries/s= 224584.862K total=-2781566150975000263ConcurrentHashMap size= 30 entries/s= 174917.912K total=-1312321443993669200ConcurrentSkipListMap size= 30 entries/s= 354581.676K total=-2600502266614288915AirConcurrentMap size= 30 entries/s= 254150.967K total=-1256373143380530839 ---------------HashMap size= 100 entries/s= 295763.376K total=-2123996537948400465TreeMap size= 100 entries/s= 225375.420K total=-2816005249627104526ConcurrentHashMap size= 100 entries/s= 168596.386K total=-1337959745143386554ConcurrentSkipListMap size= 100 entries/s= 366342.358K total=-2656351051389612808AirConcurrentMap size= 100 entries/s= 336305.468K total=-1307783105877232718 ---------------HashMap size= 300 entries/s= 335940.642K total=-2176036047793281607TreeMap size= 300 entries/s= 213798.860K total=-2849343024468137449ConcurrentHashMap size= 300 entries/s= 196158.746K total=-1368245793652746886ConcurrentSkipListMap size= 300 entries/s= 348762.198K total=-2711376732587358984AirConcurrentMap size= 300 entries/s= 435378.640K total=-1375390632080685627 ---------------HashMap size= 1000 entries/s= 312285.030K total=-2145888100702813327TreeMap size= 1000 entries/s= 157007.240K total=-2834013084542617045ConcurrentHashMap size= 1000 entries/s= 178919.552K total=-1350929801563960438ConcurrentSkipListMap size= 1000 entries/s= 253518.140K total=-2687136797657993712AirConcurrentMap size= 1000 entries/s= 449868.858K total=-1331959489090096491 ---------------HashMap size= 3000 entries/s= 269579.050K total=-2118053337323592431TreeMap size= 3000 entries/s= 129271.886K total=-2820412724828116661ConcurrentHashMap size= 3000 entries/s= 95870.060K total=-1340856888537750166ConcurrentSkipListMap size= 3000 entries/s= 203849.473K total=-2666107139705649888AirConcurrentMap size= 3000 entries/s= 443682.852K total=-1286068695711899563 ---------------HashMap size= 10000 entries/s= 100969.734K total=-2116523986910706773TreeMap size= 10000 entries/s= 81240.085K total=-2819237854014952091ConcurrentHashMap size= 10000 entries/s= 74229.656K total=-1339726640597926192ConcurrentSkipListMap size= 10000 entries/s= 147733.052K total=-2664068913299591178AirConcurrentMap size= 10000 entries/s= 399269.901K total=-1279844336850624703 ---------------HashMap size= 30000 entries/s= 77830.586K total=-2121068856388826590TreeMap size= 30000 entries/s= 73801.711K total=-2823183557187296024ConcurrentHashMap size= 30000 entries/s= 63503.394K total=-1343522194696030345ConcurrentSkipListMap size= 30000 entries/s= 148907.153K total=-2671403338078408622AirConcurrentMap size= 30000 entries/s= 450044.679K total=-1305454406448994036 ---------------HashMap size= 100000 entries/s= 57919.591K total=-2122150626578319295TreeMap size= 100000 entries/s= 39468.243K total=-2823932886520250879ConcurrentHashMap size= 100000 entries/s= 30273.873K total=-1344103393021081000ConcurrentSkipListMap size= 100000 entries/s= 48766.187K total=-2672332261897079327AirConcurrentMap size= 100000 entries/s= 307460.503K total=-1311189966514089586 ---------------HashMap size= 300000 entries/s= 42127.664K total=-2122825947560403955TreeMap size= 300000 entries/s= 26508.090K total=-2824353316156729769ConcurrentHashMap size= 300000 entries/s= 27206.845K total=-1344518179306734670ConcurrentSkipListMap size= 300000 entries/s= 19172.093K total=-2672628537815403377AirConcurrentMap size= 300000 entries/s= 152485.548K total=-1313414387297697136 ---------------HashMap size= 1000000 entries/s= 40607.148K total=-2123037200986959355TreeMap size= 1000000 entries/s= 25159.911K total=-2824487462082592448ConcurrentHashMap size= 1000000 entries/s= 30257.523K total=-1344677675643783997ConcurrentSkipListMap size= 1000000 entries/s= 37742.151K total=-2672825003502099899AirConcurrentMap size= 1000000 entries/s= 148954.277K total=-1314169618297632691 ---------------HashMap size= 3000000 entries/s= 43941.038K total=-2123087741997557902TreeMap size= 3000000 entries/s= 18891.646K total=-2824508924703531557ConcurrentHashMap size= 3000000 entries/s= 32007.894K total=-1344715062144774703ConcurrentSkipListMap size= 3000000 entries/s= 21722.543K total=-2672849927836093703AirConcurrentMap size= 3000000 entries/s= 126084.363K total=-1314312240875486125 ---------------HashMap size= 10000000 entries/s= 35724.715K total=-2123169850545290476TreeMap size= 10000000 entries/s= 12693.940K total=-2824540855805427558ConcurrentHashMap size= 10000000 entries/s= 27254.306K total=-1344783485934551848ConcurrentSkipListMap size= 10000000 entries/s= 13572.712K total=-2672886420523974847AirConcurrentMap size= 10000000 entries/s= 92726.047K total=-1314522073830802703 ---------------6.總結(jié)
使用某些預(yù)防措施的簡(jiǎn)單代碼,可以獲得可重復(fù)的,有意義的自定義Map性能測(cè)試。 此代碼顯示了其中一些問(wèn)題。 該代碼可輕松適應(yīng)其他類(lèi)型的Map測(cè)試和數(shù)據(jù)輸出格式。
翻譯自: https://www.javacodegeeks.com/2017/04/simple-map-iterator-performance-test.html
總結(jié)
以上是生活随笔為你收集整理的一个简单的Map Iterator性能测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: linux中for循环语句(linux中
- 下一篇: 中小企业划分标准(中小企业ddos)