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


当前回答

为微优化人员准备的序言

记住:

程序员浪费了大量的时间去思考或担心程序中非关键部分的速度,而当考虑到调试和维护时,这些提高效率的尝试实际上会产生强烈的负面影响。我们应该忘记小的效率,大约97%的时候:过早的优化是万恶之源。但我们不应该错过这关键的3%的机会。”

(感谢metamorphosis的完整引用)

不要使用C数组来代替向量(或任何东西),因为你认为它更快,因为它应该是低级别的。你可能错了。

使用默认的向量(或者根据需要使用安全的容器),然后如果你的分析器说这是一个问题,看看你是否可以优化它,要么使用更好的算法,要么改变容器。

话虽如此,我们可以回到最初的问题。

静态/动态数组?

c++数组类比低级C数组表现得更好,因为它们了解自己很多东西,并且可以回答C数组不能回答的问题。他们能够自己打扫卫生。更重要的是,它们通常是使用模板和/或内联编写的,这意味着在调试中出现的大量代码在发布版本中分解为很少或没有代码,这意味着它们与内置的不太安全的竞争没有区别。

总而言之,它分为两类:

动态数组

使用指向malloc-ed/new-ed数组的指针最多和std::vector版本一样快,但安全性要低得多(参见litb的帖子)。

所以使用std::vector。

静态数组

最好使用静态数组:

和std::array版本一样快 更不安全。

所以使用std::array。

未初始化的内存

有时,使用一个向量而不是一个原始缓冲区招致一个可见的成本,因为向量将在构造时初始化缓冲区,而它所取代的代码没有,正如bernie by在他的回答中所说。

如果是这种情况,那么您可以通过使用unique_ptr而不是vector来处理它,或者,如果这种情况在您的代码线中不是例外,实际上编写一个类buffer_owner,它将拥有该内存,并让您轻松安全地访问它,包括调整它的大小(使用realloc?)或任何您需要的奖励。

其他回答

如果不需要动态调整大小,则会有存储容量的内存开销(一个指针/size_t)。就是这样。

选择STL。没有性能损失。这些算法非常高效,它们在处理我们大多数人不会想到的细节方面做得很好。

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

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

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

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

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

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

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

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

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

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