• Effective_STL 学习笔记(十四) 使用 reserve 来避免没必要的重新分配


    对于vector和string,当需要更多的空间,以realloc等价的思想来增长。类似于realloc的操作有四个部分:

      1. 分配新的内存块,它有容器目前容量的几倍。大部分实现中,vector和string的容量以2为因数增长。

       也就是说,当容器必须扩展时,它的容量每次翻倍。

      2. 把所有元素从容器的旧内存拷贝到它的新内存。

      3. 销毁旧内存中的对象。

      4. 回收旧内存。

    这些步骤都是很昂贵的,而且所有指向 vector 和 string 中的迭代器、指针和引用都会失效。

    在标准容器中,只有 vector 和 string 提供了所有这四个相关的成员函数:

      1. size() 告诉你容器中多少个元素;

      2. capacity() 告诉你容器在它已经分配的内存中可以容纳多少元素;

      3. resize( Container::size_type n ) 强制把容器改为容纳 n 个元素。

      4. reserve( Container::size_type n ) 强制容器把它的容量改为至少 n,提供 n 不小于当前大小 

    以上,只要有元素插入而且容器的容量不足时就会发生重新分配(包括它们维护的原始内存分配和回收,对象的拷贝和析构和迭代器、指针和引用的失效)。所以避免重新分配的关键是使用 reserve 尽快把容器的内容设置为足够大,最好在容器被构造之后立刻进行。

    1   vector<int> v;
    2   v.reserve(1000);
    3   for( int i = 1; i <= 1000; i++ )
    4     v.push_back(i);

    这样循环中不会重新分配。

    在大小和容量的关系让我们可以预言什么时候插入将引起 vector 或 string 执行重新分配

    1   string s;
    2   . . .
    3   if( s.size() < s.capacity() )
    4     s.push_back( 'x' );

    回顾本条款的主旨,通常两种情况使用 reserve 来避免不必要的重新分配:

      1. 确切或者大约知道有多少元素最后出现在容器中。

      2. 保留可能需要的最大空间,然后,添加数据完成,修掉多余的容量

  • 相关阅读:
    【focus-lei 】微服务
    queryURLParams
    时间字符串的处理
    str.charAt()与str[]的区别
    数组去重函数封装
    数组去重的几种方法
    splice与slice区别
    变量与属性名的区别
    parseInt parseFloat Number三者转换的方式
    原生js实现选项卡样式切换的几种方式。
  • 原文地址:https://www.cnblogs.com/kidycharon/p/10009694.html
Copyright © 2020-2023  润新知