Effective STL 學習筆記14: Use reserve to avoid unnecessary reallocations.

vector 和 string 容器在動態插入一個新的對象時,若是容器內空間不夠,該容器會:java

  1. 從新分配空間
    一般的作法是分配當前 Capacity 大小兩倍的空間。
  2. 將舊空間中的全部元素拷貝進新的空間中。
  3. 銷燬原有空間中存儲的對象。
  4. 銷燬原有的空間。

可見一個簡單的操做背後實際可能會有許多動做。 c++

例如若是想建立一個容器讓其存放 1 ~ 1000 這 1000 個 int 值,若是用下面的方法: sql

vector<int> v;
for (int i = 1; i < 1001; ++i)
{
    v.push_back(i)
}

典型狀況下該過程將會致使約 2 ~ 10 次內存的從新分配 (前面提過,容器內存分配時,典型的方式是空間加倍,則內存從 \(1*sizeof(int)\) 增加倒 \(1000*sizeof(int)\) 約須要 10 次 (\(2^{10} = 1024\))。)bash

咱們能夠在容器建立以後經過 Reserve 來顯式地讓容器預先分配好足夠的空間來減小頻繁的 reallocation,形如:函數

vector<int> v;
v.reserve(1000);
for (int i = 1; i < 1001; ++i)
{
    v.push_back(i)
}

另外,簡單總結一下 vector 和 string 提供的 size 相關函數:post

  • size()
    告之容器內 存放了 多少元素。它並不告之容量。
  • capacity()
    告之該容器 能夠 存放多少元素。咱們能夠經過 \(capacity() - size()\) 來計算剩餘的空間。
  • resize(size_t n)
    該函數強制讓容器將保存的元素數量從當前數量變成 n 。
    • 若是 n 比當前的容納的元素數量小,則 Capacity 不變,但 n 之後的元素被銷燬。
    • 若是 n 更大,則先從新分配內存 (改變了 Capacity),而後調用元素的 Default Constructer 來初始化須要填充的內存。
  • reserve(size_t n)
    該函數讓容器至少能夠容納 n 個元素:
    • n > 當前 capacity: 從新分配空間,改變 Capacity,但不影響 size。
    • n < 當前 capacity: nothing is changed.
相關文章
相關標籤/搜索