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. 保留可能需要的最大空間,然後,新增資料完成,修掉多餘的容量