高效的使用STL

2021-07-10 22:19:06 字數 3443 閱讀 1740

僅僅是個選擇的問題,都是stl,可能寫出來的效率相差幾倍; 

熟悉以下條款,高效的使用stl;

1)stl基於拷貝的方式的來工作,任何需要放入stl中的元素,都會被複製; 

這也好理解,stl工作的容器是在堆內開闢的一塊新空間,而我們自己的變數一般存放在函式棧或另一塊堆空間中;為了能夠完全控制stl自己的元素,為了能在自己的地盤隨心幹活;這就涉及到複製; 

而如果複製的物件很大,由複製帶來的效能代價也不小 ; 

對於大物件的操作,使用指標來代替物件能消除這方面的代價; 

2)只涉及到指標拷貝操作, 沒有額外類的建構函式和賦值建構函式的呼叫;

vecttor 

<

bigobj

>

vt1;

vt1.

push_bach

(mybigobj

);vecttor

<

bigobj

*>

vt2;

vt2.

push_bach

(new

bigobj

());

注意事項: 

1)容器銷毀前需要自行銷毀指標所指向的物件;否則就造成了記憶體洩漏; 

2)使用排序等演算法時,需要構造基於物件的比較函式,如果使用預設的比較函式,其結果是基於指標大小的比較,而不是物件的比較;

因為對於list,size()會遍歷每乙個元素來確定大小,時間複雜度 o(n),線性時間;而empty總是保證常數時間;

使用區間成員函式有以下好處: 

1)更少的函式呼叫 

2)更少的元素移動 

3)更少的記憶體分配

例:將v2後半部的元素賦值給v1: 

單元式操作:

for

(vector

<

widget

>::

const_iterator ci =v2

.begin()+

v2.size()/

2;ci !=v2.

end();

++ci)v1

.push_back

(*ci

)

使用區間成員函式assign():

v1

.assign(v2

.begin()+

v2.size()/

2,v2.

end());

新增元素空間不夠時,vector會進行如下操作: 

1)分配當前空間的兩倍空間; 

2)將當前元素拷貝到新的空間中; 

3)釋放之前的空間; 

4)將新值放入新空間指定位置;

如果預先知道空間的大小,預先分配了空間避免了重新分配空間和複製的代價; 

注:reserve()只是修改了容量,並非大小,向vector中增加元素還是需要通過push_back加入;

對階段性操作的定義: 

先做一系列插入、完成之後,後續操作都是查詢;

在階段性的操作下,使用vector有以下優勢: 

1)因為vector有序,關聯容器帶來的有序優勢散失; 

2)都是使用二分法查詢的前提下,查詢演算法對連續的記憶體空間的訪問要快於離散的空間;

插入時,insert效率高;因為operator會先探查是否存在這個元素,如果不存在就構造乙個臨時的,然後才涉及到賦值,多了乙個臨時物件的構造; 

更新時,[]效率更高,insert會創造乙個物件,然後覆蓋乙個原有物件;而[]是在原有的物件上直接賦值操作;

雜湊函式的預設比較函式是equal_to,因為不需要保持有序;

1)效率相比手寫更高; 

stl的**都是c++專家寫出來的,專家寫出來的**在效率上很難超越; 

除非我們放棄了某些特性來滿足特定的需求,可能能快過stl;比如,基於特定場合下的程式設計,放棄通用性,可移植性; 

2)不容易出錯; 

3)使用高層次思維程式設計 

相比彙編而言,c是高階語言;一條c語言語句,用彙編寫需要好幾條; 

同樣的,在stl的世界中,我們也有高層次的術語: 

高層次的術語:insert/find/for_each(stl演算法) 

低層次的詞彙:for /while(c++語法) 

用高層次術語來思考程式設計,會更簡單;

1)基於效率考慮,成員函式知道自己這個容器和其他容器有哪些特有屬性,能夠利用到這些特性;而通用演算法不可以; 

2)對於關聯容器,成員函式find基於等價搜尋;而通用演算法find基於相等來搜尋;可能導致結果不一樣;

因為內聯,在函式物件的方式中,內聯有效,而作為函式指標時,一般編譯器都不會內聯函式指標指向的函式;即使指定了inline; 

比如:

inline

bool

doublegreater

(doubled1,

doubled2)

vectorv;

...sort(v

.begin

(),v

.end

(),doublegreater

);

這個呼叫不是真的把doublegreater傳給sort,它傳了乙個doublegreater的指標。 

更好的方式是使用函式物件:

sort(v

.begin

(),v

.end

(),greater

())

注:《effcient c++》中的實驗結論,使用函式物件一般是裸函式的1.5倍,最多能快2倍多

需要排序前思考我們的必要需求,可能我們只是需要前多少個元素,這時並不需要使用sort這種線性時間的工具,效能消耗更少的parttition可能是更好的選擇; 

以下演算法的效率從左到右依次遞減:

partition 

>

stable_partition

/nth_element

/patical_sort

/sort

/stable_sort

功能說明: 

partition :將集合分隔為滿足和不滿足某個標準兩個區間; 

stable_partition :partition的穩定版本; 

nth_element :獲取任意順序的前n個元素; 

patical_sort :獲取前n個元素,這個n個元素已排序; 

sort:排序整個區間; 

stable_sort:sort的穩定版本;

為什麼vector不提供push_front()成員方法?因為效率太差,如果有太多從前面插入的需求,就不應該使用vector,而用list; 

關心查詢速度,首先應該考慮雜湊容器(非標準stl容器,如:unordered_map,unordered_set);其次是排序的vector,然後是標準的關聯容器;

高效的使用STL

僅僅是個選擇的問題,都是stl,可能寫出來的效率相差幾倍 熟悉以下條款,高效的使用stl 1 stl基於拷貝的方式的來工作,任何需要放入stl中的元素,都會被複製 這也好理解,stl工作的容器是在堆內開闢的一塊新空間,而我們自己的變數一般存放在函式棧或另一塊堆空間中 為了能夠完全控制stl自己的元素...

如何高效的使用STL

一些容器選用法則 1 如果程式要求隨機訪問元素,則應使用vector或deque容器 2 如果程式必須在容器的中間位置插入或刪除元素,則應採用list容器 3 如果程式不是在容器的中間位置,而是在容器首部或尾部插入或刪除元素,則應採用deque容器 4 如果只需要在讀取輸入時在容器的中間位置插入元素...

STL 什麼是STL 使用STL的好處

標準模板庫,由惠普實驗室開發的一系列的標準化的元件,目前是c 的一部分。stl的 廣義上講,分為三類 容器 迭代器 演算法,容器和演算法是通過迭代器無縫連線,string和wstring也是stl的一部分,內嵌在c 的編譯器中。特點 資料結構 容器 和演算法的分離,演算法有乙份即可,比如sort排序...