c++ 每次迭代在for循环中计算向量大小是否昂贵?

7vux5j2d  于 5个月前  发布在  其他
关注(0)|答案(6)|浏览(42)

此问题在此处已有答案

Is calling std::vector::size() as fast as reading a variable?(7个答案)
In a "i < vector.size()" loop condition, is size() called each iteration?(10个答案)
15小时前就关门了
c++编译器是否会处理像buildings is vector这样的情况:

for (int i = 0; i < buildings.size(); i++) {}

字符串
也就是说,它是否注意到建筑物是否在循环中被修改,然后基于此不在每次迭代中评估它?或者也许我应该自己做这件事,不是那么漂亮,但是:

int n = buildings.size();
for (int i = 0; i < n; i++) {}

jrcvhitl

jrcvhitl1#

buildings.size()很可能会被编译器内联,直接访问vector<T>类上的私有大小字段。所以你不应该分离对size的调用。这种微优化是你无论如何都不想担心的事情(除非你在一些被分析确定为瓶颈的非常紧密的循环中)。

bkhjykvo

bkhjykvo2#

不要从性能的Angular 来决定是否使用这两种方法;您的编译器可能会内联调用,也可能不会内联调用,而且std::vector::size()也有恒定的复杂性。
您真正应该考虑的是正确性,因为如果在迭代时添加或删除元素,两个版本的行为将非常不同。
如果在循环中没有以任何方式修改vector,请使用前一个版本,以避免一点状态(n变量)。

ngynwnxp

ngynwnxp3#

如果编译器可以确定buildings在循环中没有发生变化(例如,如果它是一个简单的循环,没有可能产生副作用的函数调用),它可能会优化计算。但是计算向量的大小是一个减法,这应该也很便宜。
以明显的方式编写代码(size在循环中),只有当分析表明它太慢时,才应该考虑替代机制。

z9zf31ra

z9zf31ra4#

我这样写循环:

for (int i = 0, maxI = buildings.size(); i < maxI; ++i)

字符串
一次处理多个问题:建议最大值预先固定,不再考虑性能损失,合并类型。如果求值在中间表达式中,则建议循环更改集合大小。
太糟糕的语言不允许合理地使用const,否则它将是const maxI。
OTOH对于越来越多的情况,我宁愿使用一些算法,lambda甚至允许使它看起来几乎像传统的代码。

apeeds0o

apeeds0o5#

假设size()函数是基本模板的内联函数,我们也可以假设它的开销很小。它与C中的strlen()有很大的不同,比如说,C中的strlen()可能有很大的开销。
使用int n = buildings.size();可能更快,因为编译器可以看到n在循环中没有变化,所以将其加载到寄存器中,而不是间接获取向量大小。(只有在分析并发现这是一个好处之后),因为在这方面,事情并不总是像你期望的那样好。

jfewjypa

jfewjypa6#

只有当它真的是一个性能问题时,才开始手动优化这样的东西。然后测量差异。否则你会得到很多不需要维护的丑陋代码,这些代码更难调试,工作效率更低。大多数领先的编译器可能会优化它,如果大小在循环中没有改变。
但是即使它没有被优化掉,那么它也可能是内联的(因为模板默认是内联的),几乎没有任何成本。

相关问题