std::vector動態擴展策略

最近幾天重溫了《STL源碼剖析》這部著作,對一些知識點做個記錄。

vector的技術實現,關鍵在於其對大小的控制以及重新配置時的數據移動效率。一旦vector舊有空間滿載,如果客戶端每新增一個元素,vector內部只是擴充一個元素的空間,實爲不智,因爲所謂擴大空間(不論多大),一如稍早所說,是“配置新空間/數據移動/釋放舊空間”的大工程,時間成本很高,應該加入某種未雨綢繆的考慮。

所謂動態增加大小,並不是在原空間之後接續新空間(因爲無法保證原空間之後上油可供配置的空間),而是以原大小的兩倍另外配置一塊較大空間,然後將原內容拷貝過來,然後纔開始在原內容之後構造新元素,並釋放原空間。因此,對vector的任何操作,一旦引起空間重新配置,指向原vector的所有迭代器舊都失效了。(摘自《STL源碼剖析》)

先來看下vector是如何拓展空間的

int main()
{
	std::vector<int> vec;
	int lastCapacity = 0;
	for (size_t i = 0; i < 100; i++)
	{
		vec.push_back(i);
		if (lastCapacity!= vec.capacity())
		{
			lastCapacity = vec.capacity();
			std::cout << i << "->" << lastCapacity << "->" << &vec[0] << "\n";
		}
		
	}
	getchar();
}

運行結果:

可以看到新增一個元素沒有剩餘空間時,就會擴展新的空間(新增加的空間約爲0.5倍的舊空間),並把內容移動到新的地址。

由於需要不斷移動數據,因此頻繁新增元素(不斷開闢新空間/移動數據)會帶來額外的時間開銷。

簡單測試下效率影響:

 

測試結果:

通過測試結果看,頻繁新增元素帶來的時間開銷還是比較大的,這還是數據比較少的情況,數據越多效率影響會越大。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章