在我们的c++课程中,他们建议不要再在新项目中使用c++数组。据我所知,Stroustroup本人建议不要使用数组。但是否存在显著的性能差异?


当前回答

为了回应Mehrdad说过的话:

然而,在某些情况下 你仍然需要数组。当 与低级代码(例如: 程序集)或旧的库 需要数组,您可能无法 用向量。

完全不是这样的。向量可以很好地降级为数组/指针,如果你使用:

vector<double> vector;
vector.push_back(42);

double *array = &(*vector.begin());

// pass the array to whatever low-level code you have

这适用于所有主要的STL实现。在下一个标准中,它将被要求工作(即使它现在做得很好)。

其他回答

有时候数组确实比向量好。如果你总是在操纵别人 固定长度的对象集合,数组更好。考虑下面的代码片段:

int main() {
int v[3];
v[0]=1; v[1]=2;v[2]=3;
int sum;
int starttime=time(NULL);
cout << starttime << endl;
for (int i=0;i<50000;i++)
for (int j=0;j<10000;j++) {
X x(v);
sum+=x.first();
}
int endtime=time(NULL);
cout << endtime << endl;
cout << endtime - starttime << endl;

}

X的向量在哪里

class X {
vector<int> vec;
public:
X(const vector<int>& v) {vec = v;}
int first() { return vec[0];}
};

X的数组版本为:

class X {
int f[3];

public:
X(int a[]) {f[0]=a[0]; f[1]=a[1];f[2]=a[2];}
int first() { return f[0];}
};

数组版本的main()将更快,因为我们避免了 每次在内部循环中“new”的开销。

(此代码由我发布到comp.lang.c++)。

应该避免使用带有new的c++数组(即使用动态数组)。这里有一个问题,你必须跟踪大小,你需要手动删除它们,做各种各样的家务。

在堆栈上使用数组也是不鼓励的,因为您没有范围检查,并且传递数组将丢失关于其大小的任何信息(数组到指针的转换)。在这种情况下,应该使用std::array,它将c++数组包装在一个小类中,并提供一个size函数和迭代器来迭代它。

现在,std::vector vs.原生c++数组(取自互联网):

// Comparison of assembly code generated for basic indexing, dereferencing, 
// and increment operations on vectors and arrays/pointers.

// Assembly code was generated by gcc 4.1.0 invoked with  g++ -O3 -S  on a 
// x86_64-suse-linux machine.

#include <vector>

struct S
{
  int padding;

  std::vector<int> v;
  int * p;
  std::vector<int>::iterator i;
};

int pointer_index (S & s) { return s.p[3]; }
  // movq    32(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

int vector_index (S & s) { return s.v[3]; }
  // movq    8(%rdi), %rax
  // movl    12(%rax), %eax
  // ret

// Conclusion: Indexing a vector is the same damn thing as indexing a pointer.

int pointer_deref (S & s) { return *s.p; }
  // movq    32(%rdi), %rax
  // movl    (%rax), %eax
  // ret

int iterator_deref (S & s) { return *s.i; }
  // movq    40(%rdi), %rax
  // movl    (%rax), %eax
  // ret

// Conclusion: Dereferencing a vector iterator is the same damn thing 
// as dereferencing a pointer.

void pointer_increment (S & s) { ++s.p; }
  // addq    $4, 32(%rdi)
  // ret

void iterator_increment (S & s) { ++s.i; }
  // addq    $4, 40(%rdi)
  // ret

// Conclusion: Incrementing a vector iterator is the same damn thing as 
// incrementing a pointer.

注意:如果你用new分配数组,并分配非类对象(如纯int)或没有用户定义的构造函数的类,并且你不想让你的元素初始化,使用new-allocated数组可以有性能优势,因为std::vector在构造时将所有元素初始化为默认值(例如int为0)(感谢@bernie提醒我)。

如果在调试模式下编译软件,许多编译器将不会内联vector的访问器函数。这将使stl向量的实现在性能有问题的情况下变得更慢。它还将使代码更容易调试,因为您可以在调试器中看到分配了多少内存。

在优化模式下,我希望stl向量接近数组的效率。这是因为许多vector方法现在都内联了。

我认为最主要的问题不是性能,而是安全性。使用数组可能会犯很多错误(例如,考虑调整大小),而使用向量可以省去很多麻烦。

如果使用向量表示多维行为,则会对性能造成影响。

2d+向量会导致性能下降吗?

其要点是,每个子向量都有大小信息,因此会有少量开销,并且不一定会有数据序列化(与多维c数组不同)。这种串行化的缺乏可以提供比微优化更大的机会。如果你在做多维数组,最好扩展std::vector并滚动你自己的get/set/resize bits函数。