STL的缺點

作者:姚冬
鏈接:https://www.zhihu.com/question/20201972/answer/41324520
來源:知乎
著作權歸作者所有,轉載請聯繫作者獲得授權。

說幾個STL的缺點吧,雖然都是在比較極端的情況下出現,但是對於一些大項目還是會遇到的

1. 代碼膨脹問題
每一個實例化過的模板類,都會膨脹出一份獨立的代碼,比如
std::vector<std::string>, std::vector<int>,編譯後會產生兩份代碼,在VC2008下,每份代碼大約是3-4kb,這是因爲vector比較簡單代碼少,如果是map則會產生30-50kb的代碼,因爲map裏有個複雜的紅黑樹。對於數據處理類的代碼裏一般會定義很多種不同的結構體,不同的結構體放到不同的容器裏,就會實例化出很多個類的代碼,我見過一個項目裏,這樣的vector就有數百個。

2. 內存使用效率問題 (以vc++2008爲例)
stl在內存使用效率上是比較低效的,比如std::string,它的sizeof大概是28,因爲它有一個內置的16字節數組,用來做小字符串優化的,就是說低於16字節的字符串都會至少佔用28字節內存,如果剛好17字節字符串,則會佔用28字節+額外分配的字符串內存,額外分配的內存是一個堆塊,又有很多浪費,相比用一個char *存儲字符串大約多佔用了一倍內存。
還有map<>,每一個map的node都是一塊獨立分配的內存,如果是 map<int, int>呢,那就很悲劇了,爲了存一個int要消耗幾十個字節,很浪費的。
如果元素數量有百萬級,那麼內存佔用就很可觀了,這種情況下建議自己實現allocator,做內存池。

3. deep copy問題
讓兩個容器的實例做賦值操作,看起來就一條語句,實際上容器裏的每個元素都執行了一次賦值操作。如果容器裏有百萬級的數據,那麼一個等號就產生了幾百萬次的構造和析構。
傳遞參數的時候一定要用 const 引用,賦值可以用 swap代替。

4. 隱式類型轉換
比如 有個函數
void doSomething(const std::string &str);
調用的時候
doSomething("hello");
能編譯執行,但是會產生一個臨時的匿名的std::string實例,把"hello"複製一遍,然後在調用完成後析構掉。如果這個發生在循環體內部有可能影響性能。

以上這些問題,在小程序裏或者數據規模不大的時候,比如容器內元素只有幾千這個規模,都不是什麼大問題,那時開發效率纔是重點,但是一旦有大數據stl容器會成爲性能瓶頸的。

我並不是主張不用STL,而是要充分了解STL的優缺點,根據應用場景做選擇。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章