C++:arr.size()是循环的一个好条件吗?

xia*_*yao 5 c++ caching for-loop

如果有一个名为arr的向量包含大量数据,那么我将打印该向量中的所有值.我会使用:

int arr_size = arr.size();
for(int i=0; i<arr_size; ++i) {//print the values}
Run Code Online (Sandbox Code Playgroud)

或者以这种方式实现它:

for(int i=0; i<arr.size(); ++i) {//print the values}
Run Code Online (Sandbox Code Playgroud)

在我看来,第一种实现方式是将向量的大小提取到缓存中,从而在第一次未命中后使条件更快.第二次实施怎么样?它慢了吗?每次满足条件时,系统是否会调用size()方法?

编辑:假设它使用的是C++.

Mic*_*ade 6

对于具有arbirary主体的循环的推广,您给出的两个变体之间存在一个关键区别:如果arr循环期间的变化大小怎么办?

对于第二种情况,如果编译器可以假设它没有改变那么它可以优化循环,因此arr.size()只调用一次,并且生成的代码变得与第一种情况大致相同.

但是如果循环体调用外部函数(极有可能)那么它就不能再做这个假设了,必须检查arr.size()每个循环迭代.

话虽如此,arr.size()这可能会对一个简单的结构成员访问产生影响,这种访问速度并不比将值存储在局部变量中慢,因此无论如何都不会有太大的好处.除非arr是一个指针或引用在这种情况下,它是一个间接的,然后访问,所以第一个版本将是一个豆蔻更快.

如果它是一个特别常见的运行循环,并且由于某种原因你必须在没有优化的情况下编译,你可能想要使用第一种情况来加速它.

随后,该代码的可读性不被削弱很多都通过一个额外的行呢?

总而言之,我会选择变体2,除非循环是一个必须紧密的内循环,在这种情况下,我会使用变量1来确定.

当然,如果元素被添加到arr循环内部并且循环需要覆盖这些元素,那么只有第二个变体才是正确的.

  • @MatthewWatson如果另一个线程正在改变事物,并且没有锁或其他同步,则它是未定义的行为.因此编译器可以假设情况并非如此. (2认同)