循环迭代 selectedItems() 的性能

performance of loops iterating over selectedItems()

我在将项目设置为选中时遇到问题...所以我看了一下 QGraphicsScene::selectedItems() function
从那以后,我对在循环中使用它感到非常紧张。

在这样的结构中:

foreach(QGraphicsItem* selectedItem, selectedItems())
{ 
    // perform action with selectedItem
}

每次迭代都会重新计算 selectedItems() 函数吗?
(我想是的,因为如果在循环中我改变选择,上面的内容会变得不稳定)

我想这会对我的代码速度产生很大影响...

所以我开始到处更改我的代码,以:

QList<QGraphicsItem*> sel = selectedItems();
foreach(QGraphicsItem* selectedItem, sel)
{ 
    // perform action with selectedItem
}

我假设这会加速程序是否正确?
(或者它会因为复制而变慢,而循环测试中的替换不会改变,如果我错了并且 selectedItems() 没有真正完成它的所有代码?)

我想知道应该避免哪些其他功能...例如 sceneRect()boundingRect() 用于继承自 QGraphicsItem 的项目...将它们复制到QRectF 如果在同一个函数中多次使用 ?

foreach(QGraphicsItem* selectedItem, selectedItems())
{ 
    // perform action with selectedItem
}

在这种情况下,您要遍历 returned 选定的项目,正如您发现的那样,如果更改了选择,这可能会导致问题。

这样更好吗?

QList<QGraphicsItem*> sel = selectedItems();
foreach(QGraphicsItem* selectedItem, sel)
{ 
    // perform action with selectedItem
}

简单的答案是肯定的。

will it make it slower because of copying

不一定。如果容器不变,则不会有什么不同。

但是,Qt 实现了 implicit sharing,它确保容器(例如 QList)在这种情况下共享数据,并且只制作一个副本(COW - 写时复制),当其中一个副本发生变化时.

我不会太担心 sceneRectboundingRect,因为它们只是 return 简单的数据类型,例如 QRectF,而不是项目的容器,所以这里不需要隐式共享。只有在极端情况下,缓存这样的 returned 值才会产生显着差异。