向量是否使用一个解除引用来访问元素而不是std :: array?

时间:2015-02-11 22:56:37

标签: c++ arrays performance vector

要访问std :: vector的元素,必须通过解除引用向量数据成员指针来定位向量的开头。每次访问一个向量元素时,这个指针都会发生去反射吗?或者只发生一次?

3 个答案:

答案 0 :(得分:1)

我相信。 Vector的底层数组可以重新分配,因为它需要在连续的回推时进行扩展。所以指向这个数组的指针可能会改变。

答案 1 :(得分:1)

也许,有时候。这在很大程度上取决于具体情况,以及您如何使用它。

通常,可以优化开销,例如,

vector<int> v(100);

for(i = 0; i < 100; i++)
{
   v[i] = i;
}

应该在一个不错的编译器中,只有一个额外的加载指令才能在循环之前获取vector的内部缓冲区,然后在整个循环中使用该值。

答案 2 :(得分:1)

正如Mats所说,这取决于编译器。如果我们看一个简单的例子:

#include <vector>

int vector_function(std::vector<int> & v){
    v[3] = v[1];
    v[2] = v[4];
    return v[1];
}

int array_function(int *a){
    a[3] = a[1];
    a[2] = a[4];
    return a[1];
}

然后用gcc -c -O2编译,并在.o文件上运行objdump -S,我们得到:

for vector_function:
   0:   48 8b 17                mov    (%rdi),%rdx
   3:   8b 42 04                mov    0x4(%rdx),%eax
   6:   8b 4a 10                mov    0x10(%rdx),%ecx
   9:   89 42 0c                mov    %eax,0xc(%rdx)
   c:   89 4a 08                mov    %ecx,0x8(%rdx)
   f:   c3                      retq   

for array_function:
  10:   8b 47 04                mov    0x4(%rdi),%eax
  13:   8b 57 10                mov    0x10(%rdi),%edx
  16:   89 47 0c                mov    %eax,0xc(%rdi)
  19:   89 57 08                mov    %edx,0x8(%rdi)
  1c:   c3                      retq   

我们看到向量情况中确实只有一条额外的指令(mov (%rdi),%rdx,它加载向量的内部指针)

请注意,这仅适用于优化(特别是内联) - 否则vector_function的反汇编完全混乱(为每次访问调用函数)