簡體   English   中英

Java中List.get的for循環的等效項

[英]Equivalence of for loop to List.get in java

我有一個包含一個元素的列表,但以后可能會有更多。 我正在使用的列表是一個ArrayList。 我發現通過調用List.get(0)而不是使用for循環,可以獲得更快的結果。 為什么是這樣? 循環播放1個項目不應該等於獲得1個項目嗎? 如果沒有,我如何獲得類似的性能? 我知道我的數組最終將大於一個項目。 我在opengl渲染器的主體中使用此循環。 當我使用循環時,我的fps下降了45。

編輯 :我已經解決了問題。 每次渲染時,我的渲染器都會在列表中添加一個新值。

在Java中使用增強的for循環(每個循環)會生成如下所示的已編譯代碼:

Iterator<Thing> it = list.iterator();
while(it.hasNext()) {
  yourLoop.loopBody(it.next());
}

您可能期望它與此等效?

for (int i = 0; i < list.size(); i++) {
  yourLoop.loopBody(list.get(i));
}

但是情況並非如此,構造迭代器需要花費額外的時間。

在不知道List實現的情況下,無法真正給出具體答案。 例如, ArrayList由數組支持,因此調用get本質上是對數組的訪問。

另一方面,使用for循環的“ foreach”版本需要創建Iterator 這可能是速度變慢的原因。 一些實現對IteratorListIterator具有復雜的實現。

答案是樣式和可讀性問題。 大多數Java程序員都會說foreach循環更具可讀性,並且沒有意圖。 使用List某些實現(例如LinkedList )要快得多。

我不是Collections方面的專家,但是設置迭代必須比僅僅獲取特定項目要昂貴得多。

通過設置一個foreach,我們不知道集合中有多少個項目,因此無論列表中有多少個項目,它都會將其設置為迭代。

通常,如果您擔心速度,那么如果知道使用ArrayList,則最快的方法是:

int size = list.size();
for (int i=0;i<size;i++) {
  Thing thing = list.get(i);
}

盡管“ size”方法的開銷很小,但是仍然需要在每個循環中都不調用它。 ArrayList上的get()方法為O(1)。 這應該賦予Iterator類似的性能。 如果您看一下ArrayList的迭代器代碼,這很簡單,唯一真正的額外開銷是來自對象創建和並發修改檢查。

但是,對於LinkedList,這種類型的循環會產生可怕的性能,因為LinkedList上的.get()方法為O(n),並且Iterator會更快,因為它只需為每次迭代進行指針檢查和重新分配,這使得每次調用next()都為O(1)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM