STL容器 vector,list,deque 性能比較

C++的STL模板庫中提供了3種容器類:vector,list,deque
對於這三種容器,在以爲好用的同時,常常會讓咱們困惑應該選擇哪種來實現咱們的邏輯。
在少許數據操做的程序中隨便哪種用起來感受差異並非很大,
可是當數據達到必定數量後,會明顯感受性能上有很大差別。

本文就試圖從介紹,以及性能比較兩個方面來討論這個問題。html

 

    1. vector - 會自動增加的數組

 

    1. list - 擅長插入刪除的鏈表

 

    1. deque - 擁有vector和list二者優勢的雙端隊列

 

    1. 性能競技場

 

    1. 性能總結與使用建議

 

    1. 測試程序清單

 

 

vector - 會自動增加的數組

vector又稱爲向量數組,他是爲了解決程序中定義的數組是
不能動態改變大小這個缺點而出現的。
通常程序實現是在類建立的時候同時建立一個定長數組,
隨着數據不斷被寫入,一旦數組被填滿,則從新開闢一塊更大的內存區,
把原有的數據複製到新的內存區,拋棄原有的內存,如此反覆。

因爲程序自動管理數組的增加,對於咱們程序員來講確實輕鬆了很多,
只管把數據往裏面插就好了,固然把物理內存和虛擬內存插爆掉了
就是操做系統來找你麻煩了:-)

vector因爲數組的增加只能向前,因此也只提供了後端插入和後端刪除,
也就是push_back和pop_back。固然在前端和中間要操做數據也是能夠的,
用insert和erase,可是前端和中間對數據進行操做必然會引發數據塊的移動,
這對性能影響是很是大的。

對於全部數組來講,最大的優點就是隨機訪問的能力。
在vector中,提供了at和[]運算符這兩個方法來進行隨機訪問。
因爲每一個數據大小相同,而且無間隔地排列在內存中,
因此要對某一個數據操做,只須要用一個表達式就能直接計算出地址:
address = base + index * datasize

一樣,對vector進行內存開闢,初始化,清除都是不須要花大力氣的,
從頭至尾都只有一塊內存。前端

 

list - 擅長插入刪除的鏈表

有黑必有白,世界萬物都是成對出現的。
鏈表對於數組來講就是相反的存在。
數組自己是沒有動態增加能力的(程序中也必須從新開闢內存來實現),
而鏈表強悍的就是動態增加和刪除的能力。
但對於數組強悍的隨機訪問能力來講的話,鏈表卻很弱。

list是一個雙向鏈表的實現。
爲了提供雙向遍歷的能力,list要比通常的數據單元多出兩個指向先後的指針。
這也是沒辦法的,畢竟如今的PC內存結構就是一個大數組,
鏈表要在不一樣的環境中實現本身的功能就須要花更多空間。

list提供了push_back,push_front,pop_back,pop_front四個方法
來方便操做list的兩端數據的增長和刪除,不過少了vector的at和[]運算符的
隨機訪問數據的方法。並非不能實現,而是list的設計者
並不想讓list去作那些事情,由於他們會作得很是差勁。

對於list來講,清除容器內全部的元素是一件苦力活,
由於全部數據單元的內存都不連續,list只有一個一個遍從來刪除。程序員

 

deque - 擁有vector和list二者優勢的雙端隊列

黑與白,處於這兩個極端之間的就是使人愉悅的彩色了。
deque做爲vector和list的結合體,確實有着不凡的實力。

STL的deque的實現沒有怎麼去看過,不過根據我本身的猜想,
應該是把數組分段化,在分段的數組上添加指針來把全部段連在一塊兒,
最終成爲一個大的數組。

deque和list同樣,提供了push_back,push_front,
pop_back,pop_front四個方法。能夠想象,若是要對deque的兩端進行操做,
也就是要對第一段和最後一段的定長數組進行從新分配內存區,
因爲分過段的數組很小,從新分配的開銷也就不會很大。

deque也和vector同樣,提供了at和[]運算符的方法。
要計算出某個數據的地址的話,雖然要比vector麻煩一點,
但效率要比list高多了。
首先和list同樣進行遍歷,每次遍歷的時候累積每段數組的大小,
當遍歷到某個段,並且baseN <= index < baseN + baseN_length的時候,
經過address = baseN + baseN_index就能計算出地址
因爲分過段的後鏈表的長度也不是很長,因此遍歷對於
總體性能的影響就微乎其微了。

看起來deque很無敵吧,不過deque和希臘神話的阿吉里斯同樣,
再怎麼強大也是有本身的弱點的,以後的測試數據中就能看到了。

P.S.請搜索「阿吉里斯的腳後跟」來獲取詳細內容後端

相關文章
相關標籤/搜索