本人原創,轉載請註明出處
在做項目遍歷ArrayList裏面的數據時突然無聊的想試試ArrayList各種遍歷方法的效率比較,本來只想到iterator和for的測試,但是在寫類的時候心想反正寫兩個了,就多寫一個吧,
以前學c++時覺得hook這東西非常神奇,趁機也用在這裏,這好像還是個設計模式叫模版設計模式來着
public abstract class Hook {
protected Hook() {
long start = System.currentTimeMillis();
// 懶得寫循環,直接複製
test();
test();
test();
test();
test();
long end = System.currentTimeMillis();
System.out.println("用時:" + (end - start) + "毫秒");
}
/**
* 只要繼承了這個抽象類就要重寫這個方法,只管往這裏寫東西,
* 然後製造對象的時候,自然會調用這個方法
* 是不是很神奇啊,跟變魔術一樣
*/
abstract void test();
}
然後幾個測試的類繼承Hook就好
,這是測試iterator用時的類
<span style="font-family:KaiTi_GB2312;">public class Test1 extends Hook {
private static int Times = 100000;
/**
* @param args
*/
public static void main(String[] args) {
new Test1();
}
@Override
void test() {
ArrayList<Integer> al = new ArrayList<>();
for (int i = 0; i < Times; i++) {
al.add(i);
}
// iterator spends time
Iterator<Integer> iterator = al.iterator();
while (iterator.hasNext()) {
Integer next = iterator.next();
System.out.print(next);
}
}
}</span>
public class Test2 extends Hook {
private static int Times = 100000;
/**
* @param args
*/
public static void main(String[] args) {
new Test2();
}
@Override
void test() {
ArrayList<Integer> al = new ArrayList<>();
for (int i = 0; i < Times; i++) {
al.add(i);
}
// for loops spends time
for (int i = 0; i < al.size(); i++) {
Integer next = al.get(i);
System.out.print(next);
}
}
}
這是測試增強for循環的類,我還是百度翻譯一下才知道增強for循環怎麼寫...
public class Test3 extends Hook {
private static int Times = 100000;
/**
* @param args
*/
public static void main(String[] args) {
new Test3();
}
@Override
void test() {
ArrayList<Integer> al = new ArrayList<>();
for (int i = 0; i < Times; i++) {
al.add(i);
}
// Enhanced for loop spends time
for (Integer next : al) {
System.out.println(next);
}
}
}
然後就是測試結果啦,本來是運行一次測試一次的,但是太麻煩了,索性一次測試5次,本來測試類中不用寫在遍歷的時候打印東西的,但是怕編譯器太智能將循環跳過編譯的.
我是一邊寫這篇文章一邊測試的,結果電腦太渣,運行了好半天沒結果,上面就都減去了一個零;
不知道爲什麼,只有最後一個的遍歷時打印的值顯示了,三個各運行了5次,結果分別是:
第一次:
979999899999用時:3226毫秒
999899999用時:3144毫秒
用時:5011毫秒
第二次:
79999899999用時:3415毫秒
9979999899999用時:3315毫秒
用時:4929毫秒
第三次:
99999用時:3273毫秒
9999用時:3434毫秒
用時:4891毫秒
第四次:
99899999用時:3327毫秒
9用時:3438毫秒
用時:4851毫秒
第五次:
9999用時:3292毫秒
99899999用時:3275毫秒
iterator和for循環的測試類控制檯什麼都沒打印,但是複製出來前面就多出了一串數字,不知道是怎麼回事
我不知道是不是在控制檯打印的原因導致增強for循環更慢,我以前聽說增強for循環底層還是Iterator實現的,猜測會慢一點,但是一直沒時間查看源碼,以後有機會再找找源代碼看一看,把今天測試結果的原因分析一下補全博客,我把測試增強for循環的代碼修改了一下,然後不知道是不是編譯器給我優化了
<span style="white-space:pre"> </span>int i = 0;
// Enhanced for loop spends time
for (Integer next : al) {
i += next;
}
System.out.println(i);
結果是
704982704
704982704
704982704
704982704
704982704
用時:35毫秒
然後我把所有測試的類遍歷過程中的輸出都換成了類似這種形式,結果用時都大爲減少,而且結果相差不大,
爲測試是不是編譯器的優化我又給循環次數加了兩個0
測試兩遍用時分別爲
用時:11512毫秒
用時:11190毫秒
用時:11761毫秒
用時:11359毫秒
用時:11485毫秒
用時:11390毫秒
這次測試不一定嚴謹,我會總結經驗,再接再厲.ps:字體真彆扭,感覺怎麼換都好醜