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


当前回答

在c++ 11中使用普通数组的理由就更少了。

从最快到最慢,本质上有3种类型的数组,这取决于它们所具有的特性(当然,实现的质量可以使事情变得非常快,即使是列表中的情况3):

静态的,在编译时大小已知。——std::array<T, N> 动态的,运行时大小已知,从不调整大小。这里的典型优化是,如果数组可以直接分配到堆栈中。——不可用。也许在c++ 14之后,在c++ TS中使用dynarray。在C中有vla 动态的,可在运行时调整大小。——std::向量T > <

为1。常量静态数组,在c++ 11中使用std::array<T, N>。

为2。在运行时指定固定大小的数组,但这不会改变它们的大小,在c++ 14中有讨论,但它已经转移到技术规范,最终由c++ 14制成。

为3。std::vector<T>通常会在堆中请求内存。这可能会影响性能,不过可以使用std::vector<T, MyAlloc<T>>来使用自定义分配器改善这种情况。相对于T mytype[] = new mytype[n];你可以调整它的大小它不会像普通数组那样衰减为指针。

使用上面提到的标准库类型来避免数组退化为指针。如果使用相同的特性集,将节省调试时间,并且性能与普通数组完全相同。

其他回答

两者之间的性能差异很大程度上取决于实现——如果你比较一个实现得很差的std::vector和一个优化的数组实现,数组会赢,但是反过来,vector会赢……

As long as you compare apples with apples (either both the array and the vector have a fixed number of elements, or both get resized dynamically) I would think that the performance difference is negligible as long as you follow got STL coding practise. Don't forget that using standard C++ containers also allows you to make use of the pre-rolled algorithms that are part of the standard C++ library and most of them are likely to be better performing than the average implementation of the same algorithm you build yourself.

也就是说,以我之见,vector在使用调试STL的调试场景中胜出,因为大多数具有适当调试模式的STL实现至少可以突出/清除人们在使用标准容器时所犯的典型错误。

哦,不要忘记数组和vector共享相同的内存布局,因此您可以使用vector将数据传递给需要基本数组的遗留C或c++代码。但是,请记住,在这种情况下,大多数赌注都是无效的,您将再次处理原始内存。

可能会有一些边缘情况,你在内联函数中有一个向量访问在内联函数中,你已经超出了编译器将内联的范围,它将强制函数调用。这种情况太罕见了,不值得担心——总的来说,我同意litb的观点。

我很惊讶居然没有人提到这一点——不要担心性能,直到它被证明是一个问题,然后进行基准测试。

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

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

STL is a heavily optimized library. In fact, it's even suggested to use STL in games where high performance might be needed. Arrays are too error prone to be used in day to day tasks. Today's compilers are also very smart and can really produce excellent code with STL. If you know what you are doing, STL can usually provide the necessary performance. For example by initializing vectors to required size (if you know from start), you can basically achieve the array performance. However, there might be cases where you still need arrays. When interfacing with low level code (i.e. assembly) or old libraries that require arrays, you might not be able to use vectors.

向量是底层的数组。 性能是一样的。

一个可能会遇到性能问题的地方是,vector的大小一开始就不正确。

当一个vector容器被填充时,它将调整自身的大小,这可能意味着,一个新的数组分配,然后是n个复制构造函数,然后是大约n个析构函数调用,然后是一个数组删除。

如果你的构造/销毁是昂贵的,你最好让向量的正确大小开始。

有一种简单的方法可以证明这一点。创建一个简单的类,显示它何时被构造/销毁/复制/赋值。创建一个这些东西的向量,并开始将它们推到向量的后端。当向量被填充时,随着向量大小的调整,将会有一连串的活动。然后再试一次,将向量大小调整为预期的元素数量。你会发现其中的不同。