我一直在浏览一些 Qt 代码(初学者级别),我遇到了这一点:
QList<QGraphicsItem*> items{ collidingItems(mPlayer) };
for (int i{ 0 }, total{ items.count() }; i < total; ++i)
if (condition())
soSomething();
我从未见过 count()(或容器的 size())的结果被缓存,我一直假设编译器对其进行了优化。可以?此外,如果没有,则缓存值是值得的,因为我以前从未在 for 循环中看到过它,即使对于巨大的容器大小也是如此。
最佳答案
如果 condition()
和 doSomething()
函数在不同的翻译单元中,编译器无法内联它们,也不知道它们的副作用。这些函数可能产生的副作用之一是它们会在 items
列表中添加或删除元素。因此,编译器无法缓存 items.count()
,因为它可能会在循环期间发生变化。在这种情况下,手动将大小缓存到局部变量中可以使代码更快。
参见 https://godbolt.org/g/3co2Cb举个例子(使用 std::vector
而不是 QList
因为 godbolt 没有 Qt 库,尽管它应该非常相似)。在该示例中,可以看到通过 -O2
优化,手动缓存到局部变量中确实会产生更快的代码。
请注意,这个答案不能一概而论,这完全取决于具体情况,取决于编译器优化和内联的积极程度,是否启用链接时优化等。
值得吗?这也取决于你的情况。如果 condition()
和 doSomething()
做了重要的工作,那么对 items.size()
的调用可能与整体速度无关循环。如果 doSomething()
和 condition()
非常小且速度很快,那么 items.size()
开销可能很重要 - 但即便如此,这仅在 for 循环是您需要优化的应用程序中的热点时才重要。
关于c++ - QList::count() 的缓存结果,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49835307/