关于foreach循环和性能的几个问题

时间:2010-06-09 11:37:33

标签: c++ qt4

我在下面有几个与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制作了列表的副本,是否可以像在

中一样更改foreach中的原始内容
QList<QGraphicsItem *> itemList = someItem->collidingItems(Qt::IntersectsItemShape);
foreach (QGraphicsItem *item, itemList) {
    if (item->type() != QGraphicsItem::UserType)
        itemList.removeOne(item);
}
// continue using itemList

3) 最后一个问题。是否有任何差异性能vise预先创建和重用指针(如下所示)或每次在foreach循环中定义一个新指针(假设一个大的列表)?

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

谢谢!

2 个答案:

答案 0 :(得分:0)

  1. 它确实将您传递的列表的副本作为foreach的第二个参数。在您的情况下,collidingItems返回的列表将被复制到foreach内使用的变量中。
  2. 是的,这没关系(见下文)。
  3. 我不认为会有性能差异,因为指针是基本类型。如果它是一个类类型,如果你在循环中声明它,那么每次迭代都必须调用它的构造函数。
  4. 来自文档:

      

    Qt在进入foreach循环时会自动获取容器的副本。如果在迭代时修改容器,则不会影响循环。 (如果不修改容器,副本仍然会发生,但由于隐式共享复制容器非常快。)

答案 1 :(得分:0)

约伯已经彻底解决了这个问题。我只想补充一点,使用foreach而不是普通for循环的性能差异可能是如此微不足道,以至于你永远无法衡量它。换句话说,这不是您应该关注的性能问题。

使用分析器来衡量代码中的瓶颈,并专注于优化实际上很慢的部分。