Arrylist三種遍歷iterator,for,增強for循環效率測試

本人原創,轉載請註明出處

  在做項目遍歷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>


這是測試for循環的類

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:字體真彆扭,感覺怎麼換都好醜

發佈了26 篇原創文章 · 獲贊 82 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章