在下面的代码中:
std::vector<int> var;
for (int i = 0; i < var.size(); i++);
Is the size()
每次循环迭代都调用成员函数,还是只调用一次?
理论上,每次都会调用它,因为 for 循环:
for(initialization; condition; increment)
body;
被扩展到类似的东西
{
initialization;
while(condition)
{
body;
increment;
}
}
(注意大括号,因为初始化已经在内部作用域中)
在实践中,如果编译器理解您的条件的一部分在整个循环期间保持不变并且它没有副作用,它可以足够聪明地将其移出。这通常是用strlen
以及类似的事情(编译器很清楚)在没有写入其参数的循环中。
然而必须注意的是,最后一个条件的证明并不总是微不足道的。一般来说,如果容器是函数的本地容器并且从不传递给外部函数,那就很容易;如果容器不是本地的(例如,它是通过引用传递的 - 即使它是const
)并且循环体包含对其他函数的调用,编译器通常必须假设这些函数可能会改变它,从而阻止长度计算的提升。
如果您知道条件的一部分评估起来“昂贵”,那么手动进行优化是值得的(而这样的条件通常不是,因为它通常归结为指针减法,这几乎肯定是内联的)。
Edit:正如其他人所说,一般来说,对于容器来说,最好使用迭代器,但是对于vector
这并不重要,因为通过随机访问元素operator[]
保证为 O(1);实际上,对于向量,它通常是指针和(向量基数+索引)和解引用与指针增量(前一个元素+1)和迭代器的取消引用。由于目标地址仍然相同,我认为您无法从缓存局部性方面从迭代器中获得一些东西(即使是这样,如果您没有在紧密循环中遍历大数组,您甚至不应该注意到这样的情况)种改进)。
对于列表和其他容器,可以使用迭代器而不是随机访问really重要的是,因为使用随机访问可能意味着每次都遍历列表,而递增迭代器只是指针取消引用。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)