2010-06-09 72 views
2

我有幾個foreach相關的問題,下面我希望有人能回答。我知道大多數人並不關心可能的微不足道的差異,但我想了解他們的完整性。有關foreach循環和性能的幾個問題

1) 有人可以解釋一下Qt中的foreach關鍵字是如何在幕後實際工作的。我想知道如果的foreach創建一個新的項對象的指針和重新評價在每次迭代的collidingItems(潛在昂貴的)在下面的示例中

foreach (QGraphicsItem *item, someItem->collidingItems(Qt::IntersectsItemShape) { 
    // do something with item; 
} 

和它應該因此被鍵入這樣

QGraphicsItem *item; 
QList<QGraphicsItem *> itemList = someItem->collidingItems(Qt::IntersectsItemShape); 
foreach (item, itemList) { 
    // do something with item; 
} 

我假設沒有,因爲根據文檔,它在進入循環之前需要一份清單的副本。但是,如果我沒有記錯,至少一個for語句會在每次迭代中評估檢查,所以我只想確定一下。

2) 第二個問題。由於的foreach使得列表的副本,它是確定在

QList<QGraphicsItem *> itemList = someItem->collidingItems(Qt::IntersectsItemShape); 
foreach (QGraphicsItem *item, itemList) { 
    if (item->type() != QGraphicsItem::UserType) 
     itemList.removeOne(item); 
} 
// continue using itemList 

3) 最後一個問題改變的foreach內原有的。是否有任何不同的性能虎鉗預先創建和重用指針(如下所示)或每次在foreach循環內定義一個新的指針(假定列表很大)?

MyGraphicsItem *myItem; // a complex subclass of QGraphicsItem 
foreach (QGraphicsItem *item, someItem->collidingItems(Qt::IntersectsItemShape)) { 
    myItem = qgraphicsitem_cast<MyGraphicsItem *>(myItem); 
    // do something with myItem; 
} 

謝謝!

回答

0
  1. 它確實複製了您作爲foreach的第二個參數傳遞的列表。在你的情況下,由collidingItems返回的列表將被複制到foreach中使用的變量中。
  2. 是的,這是可以的(見下文)。
  3. 我不認爲會有性能差異,因爲指針是一種原始類型。如果它在類的類型中,那麼如果你在循環中聲明它的構造函數,則必須在每次迭代時調用它的構造函數。

從文檔:

Qt的自動拍攝時,它進入一個foreach循環容器的副本。如果您在迭代時修改容器,則不會影響循環。 (如果你不修改容器,複製仍然會發生,但是由於隱式共享複製容器非常快。)

0

作業已經很好地回答了這個問題。我只想補充一點,使用foreach而不是普通的for循環的性能差異可能是如此微不足道以至於你永遠無法測量它。換句話說,這不是你應該關心的性能問題。

使用分析器來測量代碼中的瓶頸,並專注於優化實際上很慢的部分。