僅僅是個選擇的問題,都是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排序...