专栏名称: OSC开源社区
OSChina 开源中国 官方微信账号
目录
相关文章推荐
程艺Truman  ·  程艺Truman 20250604171709 ·  12 小时前  
极客之家  ·  22k star,微软硬核开源,让 ... ·  昨天  
码农翻身  ·  投诉领导被光速开除,和烂人说再见啦~ ·  昨天  
稀土掘金技术社区  ·  掘金 AI 编程社区- 人人都是 AI 编程家竞赛 ·  4 天前  
51好读  ›  专栏  ›  OSC开源社区

6 个技巧,提升 C++11 的 vector 性能

OSC开源社区  · 公众号  · 程序员  · 2016-12-04 08:33

正文

请到「今天看啥」查看全文


这个情况在 Scott Meyers 的书中得到了很好的解释,这本书叫 Effective STL- 50条有效使用STL的经验 :

“对于 vector 和 string,在需要更多空间的时候,会做与 realloc 等效的事情。这种类似 realloc 的操作有4个步骤:

1. 分别一个新的内存块,其容量是容器当前容量的数倍。多数实现中,vector 和 string 容量的提升因子在 1.5 和 2 之间。

2. 从容器原来占用的内存中将元素拷贝到新分配的内存中。

3. 释放原有内存中的对象。

4. 释放原有内存。

有了所有这些操作:分配、回收、拷贝和释放,如果说这些步骤(对于性能)极其昂贵,你一点都不应该感到惊讶。当然,你肯定不希望频繁的进行这样的操作。如果这还没有打动你,那么想想每次进行这些步骤的时候,vector 和 string 中所有的迭代器、指针和引用都会失效。这意味着一个简单的插入操作,对于其它使用了当前 vector 或 string 中的迭代器、指针或引用的数据结构,都有可能引起对它们进行更新。”


2.使用 shrink_to_fit() 释放 vector 占用的内存, – clear() 或 erase() 不会释放内存。

与大家所想的相反,使用 erase() 或 clear() 从 vector 中删除元素并不会释放分配给 vector 的内存。做个简单的实验就可以证明这一点。我们往一个 vector 中添加 100 个元素,然后在这个 vector 上调用 clear() 和 erase()。然后我们可以让 capacity() 函数告诉我们为这个容器分配的内存可以存入多少元素。


下面是输出:


从上面的输出可以看到,erase() 或 clear() 不会减少 vector 占用的内存。如果在代码中到达某一点,不再需要 vector 时候,请使用 std::vector::shrink_to_fit() 方法释放掉它占用的内存。

请注意,shrink_to_fit() 可能没有被所有编译器供应商完全支持。这种情况下,可以使用“Swap 惯用法”来清空 vector,代码如下:

container ( c ).swap( c ); // shrink-to-fit 惯用法,用于清空存储空间

container ().swap( c );    // 用于清空所有内容和存储空间的惯用法

如果你对此感兴趣,请查看“ C++ Coding Standards: 101 Rules, Guidelines, and Best Practices ”一书的条款# 82,其中有针对 swap 惯用法的细节介绍。


3. 在填充或者拷贝到 vector 的时候,应该使用赋值而不是 insert() 或push_back().

从一个 vector 取出元素来填充另一个 vector 的时候,常有三种方法 – 把旧的 vector 赋值给新的 vector,使用基于迭代器的 std::vector::insert() 或者使用基于循环的 std::vector::push_back()。这些方法都展示在下面:







请到「今天看啥」查看全文