C++ 什么使STL快速?

C++ 什么使STL快速?,c++,performance,stl,C++,Performance,Stl,如果以通常的方式实现一个数组类,那么它的性能要比它的STL等价物(如向量)慢。那么,是什么让STL容器/算法快速呢?标准库使用了好的算法,比如在数组(std::vector)的情况下,它通常会在每次空间用完时将存储量增加一倍,而一个幼稚的实现可能会每次增加一个元素的存储量。因为增加存储量的速度非常慢(所有现有数据都需要从旧分配复制到新分配),所以这会产生巨大的差异 类似地,所有其他算法都以相当优化的方式实现。标准库通常不在源代码级别使用任何类型的循环展开或其他此类优化。编译器只需对常规的好代码和

如果以通常的方式实现一个数组类,那么它的性能要比它的STL等价物(如向量)慢。那么,是什么让STL容器/算法快速呢?

标准库使用了好的算法,比如在数组(std::vector)的情况下,它通常会在每次空间用完时将存储量增加一倍,而一个幼稚的实现可能会每次增加一个元素的存储量。因为增加存储量的速度非常慢(所有现有数据都需要从旧分配复制到新分配),所以这会产生巨大的差异

类似地,所有其他算法都以相当优化的方式实现。标准库通常不在源代码级别使用任何类型的循环展开或其他此类优化。编译器只需对常规的好代码和简单代码(具有可怕的变量名和大量模板)进行优化


我所说的不是C++标准所规定的,而是现有实现中的共同实践。

< P> STL算法已经被数学家和计算机科学家的各级研究了很多年,他们通常使用绝对最有效的算法,您的实现可能没有使用它。常见的实现可能不是最快的,但最容易理解;STL可能正在使用一种更优化的实现。

大多数人的数组类都是通过一个恒定的增量而不是一个恒定的因子来增加大小(标准库要求)。这意味着插入一个元素需要大致的线性时间,而不是标准库的摊销常数时间。

STL算法,如
for_each
采用易于内联的函数对象。C、 另一方面,它使用的函数指针对于编译器来说要优化要困难得多

这使得一些算法(如排序算法)有很大的不同,在排序算法中,必须多次调用比较器函数

如果你感兴趣的话,维基百科已经有了

编辑:


至于STL的vector类,我认为它不一定比你在glibc中找到的更快

代码以编译器友好的方式编写,例如内联等


当然,他们使用的算法是最先进的。

除了良好的通用算法(如其他人所指出的),STL也非常有效,因为大量使用模板


有一个很好的特性,编译器会积极地优化它们。一些编译器在这方面做得非常好,可以将模板简化为给定任务所需的最小、最有效的代码。一般来说,这意味着函数尽可能内联,与特定类型交互的代码简化为最简单的形式。当然,STL的大多数实现(以及大部分Boost)都充分利用了这一点。

“通常的实现方式”是一个非常模糊的概念。每个人都以自己的方式实现它。从技术上讲,它通常不是实现的,而是重复使用的。请指定您引用的操作,以及您如何确定标准库更快。@Mehrdad,Malte:是的,我同意。但是,对于数组类来说,将元素放在中间插入一次元素,从而为新元素创建一个空的空间。此实现比向量的push_back()慢得多。我通过获取时间或时钟周期来确定它。您将插入与带有向量的数组进行比较。push_back()?这不是插入,而是附加。@Malte Clasen:@UncleBens:没错。看起来他是在比较苹果和橙子。当你达到一兆字节左右时,将存储空间增加一倍实际上是相当糟糕的……哈桑·赛义德:你永远不会浪费超过50%的分配内存。我不会称之为“相当糟糕”。显然,std::vector增长了1.5倍:@Manuel:它必须是一个常数。虽然2在大多数早期实现中使用,但1.5(大约)现在更为常见。据我所知,Andrew Koenig是第一个指出为什么应该这样做的人:@Jerry-感谢链接,很高兴知道1.5被广泛使用的原因(我认为Python列表也以同样的方式增长)。但你似乎暗示我说这不是一个恒定的因素,是什么让你这么想的?这可能是关键点之一:Dany开发者这样做应该会回报他的计算机科学degree@DrJokepu当前位置您假设开发人员拥有计算机科学学位:)+1当各种受过高等教育的人都祝福某件事时(如果他们有)不要以为你不需要考虑它。他们完全有能力也有资格犯错。-1:我想说,这根本不是一个真实的说法。“算法”是特定于实现的。仅指定STL算法/容器等的公开行为。STL有很多实现,但它们都没有经过仔细检查(事实上,我想说大多数都没有)到您声称的水平。许多实现都比一般的程序员写的好,但是一个好的程序员可以很容易地与他们竞争。。。