六一的部落格


关关难过关关过,前路漫漫亦灿灿。



容器扩容机制对一些容量的容器更优

如果可以预估容器容量并进行设置, 可以减少多次扩容带来的开销

顺序容器 支持容量管理
array X
vector(string) O
deque O
list O
forward_list O

顺序容器对容量管理操作的支持

顺序容器 查询容器容量: capacity 设置容器最小容量: reserve 释放容器多余容量: shrink_to_fit
vector(string) O O O
deque X X O
list X X X
forward_list X X X
1c.capacity();
2
3c.reserve(n);
4
5c.shrink_to_fit();

查询容器容量

capacity

不重新分配内存空间的话,容器最多可容纳的元素个数


设置容器最小容量

reserve

要求可以容纳指定个数元素

  1. 容器容量大于等于n, 不扩容
  2. 容器容量小于n, 扩容

    扩容后的容器容量大于等于n

冗余不缩小, 不够补足


释放容器多余容量

shrink_to_fit

意图使容器容量等于容器大小, 减少容器预留的内存空间

调用shrink_to_fit只是一个请求,标准库不保证一定退回内存空间


发生扩容的情况

遵循一条原则: 只有迫不得已时才分配新的内存空间

  1. 添加元素时,容器大小 size 等于容器容量 capacity
    • 第一次扩容

      1vector<int> ivec;
      2cout << " ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      3// size = 0, capacity = 0
      4
      5for (vector<int>::size_type ix = 0; ix != 24; ++ix)
      6    ivec.push_back(ix);
      7
      8cout << " ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      9// size = 24, capacity = 32
      
    • size等于capacity时停止添加元素

      1while (ivec.size() != ivec.capacity())
      2    ivec.push_back(0);
      3
      4cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      5// size = 32, capacity = 32
      6
      7// 只要没有操作需求超出vector的容量,vector没有必要扩容,也就不会重新分配内存空间
      
    • 继续添加元素, 第二次扩容

      1ivec.push_back(42);
      2
      3cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      4// size = 33, capacity = 64
      
    • 请求释放多余容量

      1ivec.shrink_to_fit();
      2cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      3// size = 33, capacity = 33
      
  2. 设置容器大小 resize 时, 元素个数 n 大于容器容量 capacity
  3. 设置容器最小容量 reserve 时, 元素个数 n 大于容器容量 capacity

vector(string)的扩张操作通常比list和deque要快


顺序容器操作: 管理容器容量


容器扩容机制对一些容量的容器更优

如果可以预估容器容量并进行设置, 可以减少多次扩容带来的开销

顺序容器 支持容量管理
array X
vector(string) O
deque O
list O
forward_list O

顺序容器对容量管理操作的支持

顺序容器 查询容器容量: capacity 设置容器最小容量: reserve 释放容器多余容量: shrink_to_fit
vector(string) O O O
deque X X O
list X X X
forward_list X X X
1c.capacity();
2
3c.reserve(n);
4
5c.shrink_to_fit();

查询容器容量

capacity

不重新分配内存空间的话,容器最多可容纳的元素个数


设置容器最小容量

reserve

要求可以容纳指定个数元素

  1. 容器容量大于等于n, 不扩容
  2. 容器容量小于n, 扩容

    扩容后的容器容量大于等于n

冗余不缩小, 不够补足


释放容器多余容量

shrink_to_fit

意图使容器容量等于容器大小, 减少容器预留的内存空间

调用shrink_to_fit只是一个请求,标准库不保证一定退回内存空间


发生扩容的情况

遵循一条原则: 只有迫不得已时才分配新的内存空间

  1. 添加元素时,容器大小 size 等于容器容量 capacity
    • 第一次扩容

      1vector<int> ivec;
      2cout << " ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      3// size = 0, capacity = 0
      4
      5for (vector<int>::size_type ix = 0; ix != 24; ++ix)
      6    ivec.push_back(ix);
      7
      8cout << " ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      9// size = 24, capacity = 32
      
    • size等于capacity时停止添加元素

      1while (ivec.size() != ivec.capacity())
      2    ivec.push_back(0);
      3
      4cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      5// size = 32, capacity = 32
      6
      7// 只要没有操作需求超出vector的容量,vector没有必要扩容,也就不会重新分配内存空间
      
    • 继续添加元素, 第二次扩容

      1ivec.push_back(42);
      2
      3cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      4// size = 33, capacity = 64
      
    • 请求释放多余容量

      1ivec.shrink_to_fit();
      2cout << "ivec: size: " << ivec.size() << " capacity: " << ivec.capacity() << endl;
      3// size = 33, capacity = 33
      
  2. 设置容器大小 resize 时, 元素个数 n 大于容器容量 capacity
  3. 设置容器最小容量 reserve 时, 元素个数 n 大于容器容量 capacity

vector(string)的扩张操作通常比list和deque要快