最近coding的時候對迴圈的效能很好奇,面對多種迴圈方式,迭代器、for迴圈、foreach迴圈、lambda的foreach迴圈。
如果單論**美觀,個人偏向於lambda的foreach迴圈和foreach迴圈。但是這樣唐突的選擇很有可能造成效能的下降。
後面本人就分析了一下各個迴圈之間的效率:
一、arraylist
size=100000
for:8
foreach:12
iterator:11
lambda:115
size=1000
for:4
foreach:1
iterator:0
lambda:98
size=10000
for:6
foreach:2
iterator:1
lambda:107
可以看出,當size很大(10萬)時候for迴圈的效能最高,當size不是很大的時候iterator和foreach效率就高。arraylist的底層是陣列形式,這不得不從它們的取數邏輯入手,如下:
(1)foreach迴圈和iterator迭代器:
foreach的底層是通過iterator迴圈,通過呼叫iterator.next(),檢視arraylist對於iterator中next方法的實現可知其最終是通過陣列下標獲取元素。
(2)for迴圈
for語句快裡直接通過下標取數
(3)lambda的foreach迴圈
開啟多執行緒併發處理
從如上遍歷、取數邏輯中可得出,for在資料量小時,由於多了index++、index對於如何選擇,總結了如下幾點,可參考
1.如果是需要對下標進行處理操作對則選擇for迴圈;
2.對於arraylist,從**簡潔講優先考慮foreach,也不用去考慮下標越界對問題;
3.對於實效性要求不高的,如i/o操作,可考慮lambda的foreach迴圈。
二、linkedlist
size=100000
for:18
foreach:10
iterator:9
lambda:108
size=10000
for:9
foreach:3
iterator:2
lambda:104
size=1000
for:4
foreach:1
iterator:0
lambda:114
此時iterator效能最佳,由於linkedlist的資料結構為鍊錶結構,其中每個節點都記錄了前驅和後繼結點(頭、尾除外)。通過下標的方式獲得值都會在鏈中檢查一遍,直到得到我們想要的下標節點為止。而iterator和foreach則是始終迴圈子節點,直到尾節點為止。考慮到**簡潔,建議使用foreach。
三、hashmap
size=100000
foreach:17
iterator:13
lambda:125
size=10000
foreach:4
iterator:3
lambda:102
size=1000
foreach:1
iterator:1
lambda:11
這裡我測試了三組資料(都是取entryset為例),不難發現
iterator迴圈始終效率方面要佔優,這裡簡單的提下hashmap的放值和取值原理。
hashmap是乙個雜湊桶,由陣列和鍊錶組成。每次put操作都會得到key的hash值
,然後根據得到的hash值選擇map陣列對應的下標存入bucket(存入
鍵物件和值物件
)。而get操作時是根據
鍵物件的hash值找map陣列中
對應的bucket,然後得到對應的值(當存在hash碰撞時,會以鍊錶的形式加在相同hash值的後面,每次get的時候呼叫keys.equals()得到該鍵與之對應的值)。
在之前的list對比中已經說明foreach迴圈底層也是由iterator實現,而lambda的foreach迴圈是充分利用cup實現多執行緒的迭代。所以不難得出hashmap遍歷
iterator效率更高一點,但是基於**簡潔性考慮也可採用foreach迴圈方式。
多重for迴圈效能分析
有人對著組合語言不夠一屑,認為那已經是古老的低階語言,是當今的非主流語言,學了也不知道有什麼用。是的,我們不得不承認,作為一門古老的語言,彙編已經完成了歷史賦予它的使命,但是我們知道,我們現在所使用的任何高階語言在編譯的時候都是被轉化為組合語言來執行的,也就是說,無論我們在上層做了何種的抽象,引入了...
java中for迴圈效能的優化 一
for 迴圈效能測試 多層for迴圈的巢狀順序 由於cpu在內外之間的切換會有一定的開銷,因此如果可能的話,應該盡可能較少內外層迴圈切換的次數.只需使最外層迴圈的次數最少,內層迴圈次數多即可.若觀點有誤請大神們多多指教 public class test2 long endtime1 system....
多重迴圈效能優化
迴圈次數較多,迴圈層數較多時,程式效率問題非常明顯。優化後的多重for迴圈可以提公升大半的效率。一 例項化變數盡量放在for迴圈體外,只例項化一次。二 普通變數改為暫存器變數,如i 改為 i。前置遞增運算避免了不必要的工作,它把值加1後直接返回改變了運算物件本身。三 條件比較使用 要快於 同理 要快...