7

根据加速 C++:

要使用这种策略,我们需要一种从向量中删除元素的方法。好消息是存在这样的设施。坏消息是从向量中删除元素的速度足够慢,以至于反对将这种方法用于大量输入数据。如果我们处理的数据变得非常大,性能会下降到惊人的程度。

例如,如果我们所有的学生都失败了,我们即将看到的函数的执行时间将与学生人数的平方成正比增长。这意味着对于一个有 100 名学生的班级,该计划的运行时间是一个学生的 10,000 倍。问题是我们的输入记录存储在一个向量中,该向量针对快速随机访问进行了优化。这种优化的一个代价是插入或删除除向量末尾以外的元素可能会很昂贵。

作者没有解释为什么向量对于 10,000 多名学生来说会如此缓慢,以及为什么在向量中间添加或删除元素通常很慢。Stack Overflow上的某个人可以为我想出一个漂亮的答案吗?

4

3 回答 3

21

拿一排房子:如果你把它们建在一条直线上,那么找到32号真的很容易:沿着大约32间房子的路走,你就到了。但是在中间添加31½号房子并不是那么有趣——这是一个很大的建设项目,对丈夫/妻子和孩子的生活造成了很大的干扰。在最坏的情况下,无论如何,道路上都没有足够的空间容纳另一所房子,所以你必须在开始之前将所有房子搬到另一条街道上。

类似地,向量连续地存储它们的数据即在内存中连续的、顺序的块中。

这对于快速找到第n元素非常有用(因为您只需沿着n 个位置移动并取消引用),但对于插入中间非常不利,因为您必须一次一个地移动所有后面的元素.

其他容器被设计为易于插入元素,但权衡是它们因此不太容易在其中找到东西。没有适合所有操作的容器。

于 2013-11-04T14:43:20.567 回答
2

When inserting elements into or removing elements from the middle of a std::vector<T> all elements after the modification point need to moved: when inserting they need to be moved further to the back, when removing they need to be moved forward to close the gap. The background is that std::vector<T> is basically just a contiguous sequence of elements.

Although this operation isn't too bad for certain types it can become comparatively slow. Note, however, that the size of the container needs to be of some sensible size or the cost of moving be significant: for small vectors, inserting into/removing from the middle is probably faster than using other data structures, e.g., lists. Eventually the cost of maintaining a more complex structure does pay off, however.

于 2013-11-04T14:45:47.547 回答
0

std::vector allocates memory as one extent. If you need to insert an element in the middle of the extend you have to shift right all elements of the vector that to make a free slot where you will nsert the new element. And moreover if the extend is already full of elements the vector need to allocate a new larger extend and copy all elements from the original extent to the new one.

于 2013-11-04T14:46:37.750 回答