Java for循環(huán)和foreach循環(huán)的性能對(duì)比分析
for循環(huán)和foreach循環(huán)的性能對(duì)比
在公司codereview過(guò)程中,發(fā)現(xiàn)一個(gè)問(wèn)題,就是有些人循環(huán)用的是普通for循環(huán),有些人用的是foreach循環(huán),它們之間有什么區(qū)別?應(yīng)該在什么時(shí)候使用這兩種循環(huán)了?
兩種循環(huán)的語(yǔ)法格式:
普通for循環(huán)語(yǔ)法
for (int i = 0; i < integers.length; i++) { System.out.println(intergers[i]); }
foreach 循環(huán)語(yǔ)法
for(Integer in : integers){ System.out.println(in); }
今天我們來(lái)比較一下兩種for循環(huán)對(duì)ArrayList和LinkList集合的循環(huán)性能比較。首先簡(jiǎn)單的了解一下ArrayList和LinkList的區(qū)別:
ArrayList
:ArrayList是采用數(shù)組的形式保存對(duì)象的,這種方式將對(duì)象放在連續(xù)的內(nèi)存塊中,所以插入和刪除時(shí)比較麻煩,查詢比較方便。LinkList
:LinkList是將對(duì)象放在獨(dú)立的空間中,而且每個(gè)空間中還保存下一個(gè)空間的索引,也就是數(shù)據(jù)結(jié)構(gòu)中的鏈表結(jié)構(gòu),插入和刪除比較方便,但是查找很麻煩,要從第一個(gè)開(kāi)始遍歷。
下面是我測(cè)試的代碼:
public class Main { public static void main(String[] args){ //實(shí)例化arrayList List<Integer> arrayList = new ArrayList<Integer>(); //實(shí)例化linkList List<Integer> linkList = new LinkedList<Integer>(); //插入10萬(wàn)條數(shù)據(jù) for (int i = 0; i < 100000; i++) { arrayList.add(i); linkList.add(i); } int array = 0; //用for循環(huán)arrayList long arrayForStartTime = System.currentTimeMillis(); for (int i = 0; i < arrayList.size(); i++) { array = arrayList.get(i); } long arrayForEndTime = System.currentTimeMillis(); System.out.println("用for循環(huán)arrayList 10萬(wàn)次花費(fèi)時(shí)間:" + (arrayForEndTime - arrayForStartTime) + "毫秒"); //用foreach循環(huán)arrayList long arrayForeachStartTime = System.currentTimeMillis(); for(Integer in : arrayList){ array = in; } long arrayForeachEndTime = System.currentTimeMillis(); System.out.println("用foreach循環(huán)arrayList 10萬(wàn)次花費(fèi)時(shí)間:" + (arrayForeachEndTime - arrayForeachStartTime ) + "毫秒"); //用for循環(huán)linkList long linkForStartTime = System.currentTimeMillis(); int link = 0; for (int i = 0; i < linkList.size(); i++) { link = linkList.get(i); } long linkForEndTime = System.currentTimeMillis(); System.out.println("用for循環(huán)linkList 10萬(wàn)次花費(fèi)時(shí)間:" + (linkForEndTime - linkForStartTime) + "毫秒"); //用froeach循環(huán)linkList long linkForeachStartTime = System.currentTimeMillis(); for(Integer in : linkList){ link = in; } long linkForeachEndTime = System.currentTimeMillis(); System.out.println("用foreach循環(huán)linkList 10萬(wàn)次花費(fèi)時(shí)間:" + (linkForeachEndTime - linkForeachStartTime ) + "毫秒"); } }
循環(huán)10萬(wàn)次的時(shí)候,控制臺(tái)打印結(jié)果:
用for循環(huán)arrayList 10萬(wàn)次花費(fèi)時(shí)間:5毫秒
用foreach循環(huán)arrayList 10萬(wàn)次花費(fèi)時(shí)間:7毫秒
用for循環(huán)linkList 10萬(wàn)次花費(fèi)時(shí)間:4481毫秒
用foreach循環(huán)linkList 10萬(wàn)次花費(fèi)時(shí)間:5毫秒
可以看出,循環(huán)ArrayList時(shí),普通for循環(huán)比f(wàn)oreach循環(huán)花費(fèi)的時(shí)間要少一點(diǎn);循環(huán)LinkList時(shí),普通for循環(huán)比f(wàn)oreach循環(huán)花費(fèi)的時(shí)間要多很多。
當(dāng)我將循環(huán)次數(shù)提升到一百萬(wàn)次的時(shí)候,循環(huán)ArrayList,普通for循環(huán)還是比f(wàn)oreach要快一點(diǎn);但是普通for循環(huán)在循環(huán)LinkList時(shí),程序直接卡死。
結(jié)論:需要循環(huán)數(shù)組結(jié)構(gòu)的數(shù)據(jù)時(shí),建議使用普通for循環(huán),因?yàn)閒or循環(huán)采用下標(biāo)訪問(wèn),對(duì)于數(shù)組結(jié)構(gòu)的數(shù)據(jù)來(lái)說(shuō),采用下標(biāo)訪問(wèn)比較好。
需要循環(huán)鏈表結(jié)構(gòu)的數(shù)據(jù)時(shí),一定不要使用普通for循環(huán),這種做法很糟糕,數(shù)據(jù)量大的時(shí)候有可能會(huì)導(dǎo)致系統(tǒng)崩潰。
for與foreach循環(huán)效率比較
對(duì)于數(shù)組來(lái)說(shuō)
for循環(huán)略慢foreach
對(duì)于鏈表來(lái)說(shuō)
for循環(huán)比f(wàn)oreach慢很多。因?yàn)閒or循環(huán)每次獲取鏈表節(jié)點(diǎn)都要重頭開(kāi)始查找,而foreach是采用迭代方式,查找節(jié)點(diǎn)只需遍歷一次,節(jié)省了很多時(shí)間。
小結(jié)一下吧
在循環(huán)操作中不涉及插入、刪除等行為時(shí),優(yōu)先使用foreach
在循環(huán)操作中涉及插入、刪除等破壞數(shù)組或鏈表原始映像行為時(shí),應(yīng)使用for
坊間傳聞,foreach的效率要比f(wàn)or的效率快8倍左右
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java模擬實(shí)現(xiàn)機(jī)場(chǎng)過(guò)安檢處理流程
這篇文章主要為大家詳細(xì)介紹了用Java模擬實(shí)現(xiàn)機(jī)場(chǎng)安全檢查流程的案例,涉及線程的相關(guān)知識(shí),由子線程不斷的檢查通過(guò)旅客,感興趣的小伙伴們可以參考一下2022-04-04SpringCloud灰度發(fā)布的設(shè)計(jì)與實(shí)現(xiàn)詳解
這篇文章主要介紹了SpringCloud灰度發(fā)布的設(shè)計(jì)與實(shí)現(xiàn)詳解,灰度從字面意思理解就是存在于黑與白之間的一個(gè)平滑過(guò)渡的區(qū)域,所以說(shuō)對(duì)于互聯(lián)網(wǎng)產(chǎn)品來(lái)說(shuō),上線和未上線就是黑與白之分,而實(shí)現(xiàn)未上線功能平穩(wěn)過(guò)渡的一種方式就叫做灰度發(fā)布,需要的朋友可以參考下2023-09-09Opencv實(shí)現(xiàn)身份證OCR識(shí)別的示例詳解
這篇文章主要為大家詳細(xì)介紹了如何使用Opencv實(shí)現(xiàn)身份證OCR識(shí)別功能,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以跟隨小編一起了解一下2024-03-03RabbitMQ冪等性與優(yōu)先級(jí)及惰性詳細(xì)全面講解
關(guān)于MQ消費(fèi)者的冪等性問(wèn)題,在于MQ的重試機(jī)制,因?yàn)榫W(wǎng)絡(luò)原因或客戶端延遲消費(fèi)導(dǎo)致重復(fù)消費(fèi)。使用MQ重試機(jī)制需要注意的事項(xiàng)以及如何解決消費(fèi)者冪等性與優(yōu)先級(jí)及惰性問(wèn)題以下將逐一講解2022-11-11Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例
本文詳細(xì)講解了Java攔截器Interceptor實(shí)現(xiàn)原理及代碼示例,對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-12-12解決在Idea 2020.2下使用 Lombok的注解不生效的問(wèn)題(插件安裝了,依賴也寫了,自動(dòng)注解也設(shè)置了)
這篇文章主要介紹了在Idea 2020.2下使用 Lombok的注解不生效的問(wèn)題(插件安裝了,依賴也寫了,自動(dòng)注解也設(shè)置了),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08使用迭代器模式來(lái)進(jìn)行Java的設(shè)計(jì)模式編程
這篇文章主要介紹了使用迭代器模式來(lái)進(jìn)行Java的設(shè)計(jì)模式編程,文中對(duì)迭代器模式中的容器封裝方面的知識(shí)進(jìn)行了講解,需要的朋友可以參考下2016-02-02