2017-08-07 264 views
3

問題是,「我們可能期望method3運行得比method2快,爲什麼會這樣?」但我不知道。看起來這兩種方法都可以執行相同的操作。有人請賜教嗎?for循環性能迭代

ArrayList<Person> method2(Person x, ArrayList<Person> people){ 
    ArrayList<Person> friends = new ArrayList<Person>(); 
    for (Person y : people) if (x.knows(y)) friends.add(y); 
    return friends; 
} 


ArrayList<Person> method3(Person x, ArrayList<Person> people){ 
    ArrayList<Person> friends = new ArrayList<Person>(); 
    for (int=0; i<people.size(); i++){ 
     Person y = people.get(i); 
     if (x.knows(y)) friends.add(y); 
    } 
    return friends; 
} 
+0

在現實世界中,99.99%的時間,這兩種方法之間唯一有意義的區別是可讀性。 2之間的性能差異取決於列表的大小,以及ArrayList如何實現get和getItorator方法,並且幾乎不會影響;任何基於類實現的設計選擇總是本質上是錯誤的(除非你需要擠出每一分性能,在這種情況下,你很可能會在較低的水平上編碼) – Tezra

回答

4

「我們可以預期方法3跑得比較快方法2,這是爲什麼?」

它可能但差異應該是最小的,甚至不考慮作爲選擇一個或另一個的信息。

這兩個方法與方差進行同樣的事情:一個加強formethod2()和訪問的Listget(int index)method3()經典for

編譯代碼method2()將導致使用迭代器,在運行時可能會稍微長一點執行但它應該沒有顯着差異。


例如:hasNext()迭代用於ArrayList進行一些檢查和一些非常微小的計算:

public E next() { 
    checkForComodification(); 
    int i = cursor; 
    if (i >= size) 
     throw new NoSuchElementException(); 
    Object[] elementData = ArrayList.this.elementData; 
    if (i >= elementData.length) 
     throw new ConcurrentModificationException(); 
    cursor = i + 1; 
    return (E) elementData[lastRet = i]; 
} 

使用該get(int index)方法A for具有較少的計算:

public E get(int index) { 
    rangeCheck(index); 

    return elementData(index); 
} 
+0

我認爲問題是要求學生認識'method2()'分配一個迭代器,但是通過現代JIT優化等,這樣做不會以任何顯着的方式減慢速度。 –

+0

@Silvio Mayolo你對教學問題是正確的。現在用迭代器編譯的代碼執行更多的計算。我更新以顯示它。這些都是極端的未成年人,但這些都超過了get()方法。就我個人而言,我無法確認JVM在優化之後對其進行零處理。 – davidxxx

+0

@davidxxx你是對的,但在這種情況下,它只適用於僅使用people.size()只需一次並將值賦給變量(不需要爲每個項調用size())。 –

5

不是這樣。兩種方法都將以幾乎相同的速度運行。

要他們不會以完全相同的速度運行的程度,兩件事情抱:

  1. 它不會讓有點區別的是任意實用的場景。

  2. 您無法確定是否會運行得更快,它是method2還是method3