[英]Nested if-statement in loop vs two separate loops
這是源代碼:
public int indexOf(Object o) {
if (o == null) {
for (int i = 0; i < size; i++)
if (elementData[i]==null)
return i;
} else {
for (int i = 0; i < size; i++)
if (o.equals(elementData[i]))
return i;
}
}
return -1;
}
為什么不這樣做:只有一個循環和if語句。
public int indexOf(Object o) {
for (int i = 0; i < size; i++){
if (o == null) {
if (elementData[i]==null)
return i;
else {
if (o.equals(elementData[i]))
return i;
}
}
return -1;
}
第一個片段必須有兩個循環,但有人說上面的代碼性能很好。 為什么?
實際上,兩個片段都是一樣的。 但是,第二個代碼段可能會執行得更糟,因為比較語句被多次評估,而不是第一個代碼段中的單個比較。 每個代碼片段經歷的循環迭代次數是相同的,但所需的比較次數不同。 就那么簡單。
我們的想法是,第一個只需將o
與null
比較一次,而第二個必須在循環中每次傳遞時將其進行比較。
使用單個循環,您必須在每次迭代時重新檢查條件 - 因此需要更多工作。
在第一個示例中,您只需檢查一次條件。
如果在沒有優化的情況下編譯(以字面方式),那么第二個例子將會更慢。
但是,大多數編譯器都有技巧,並且可以將第二個示例中的代碼轉換為與第一個示例相同的機器代碼。 但是,這在很大程度上取決於編譯器優化標志(即優化的內容 - 運行時間或代碼大小)
第二種形式檢查o == null
是否為o == null
, size - 1
次。
假設無論如何都沒有為你做這樣的優化。 如果不嘗試它就不會有什么假設。
有時在循環中的最終機器代碼中使用較少的指令也會有優勢,盡管它不太可能有任何區別。
減少可能的分支數量也可以提高性能,因為預取錯誤指令的可能性較小。 (感謝Andreas Henning)。
總之,當你需要優化某些東西時,在循環之外移動東西的想法是合理的,但在這種情況下可能不太重要。
只是看到你的評論。 考慮到有多少代碼進入ArrayList.indexOf,它是一個合理的地方,可以做你能想到的每一點點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.