作者chchwy (mat)
看板C_and_CPP
標題Re: [問題] 不傾向使用std::vector的原因
時間Sat Nov 3 19:51:46 2012
http://codepad.org/jb4Gksbm
這隻小程式可以說明vector實際上使用記憶體的狀況
藏在vector底下的並非魔術
只是把普通的動態分配記憶體給包裝起來
省下自己手動管理的麻煩而已
當vector恰好持有4個元素大小的記憶體
而你又想要插入第五個元素時,vector內部會怎麼做呢?
vector做的事情很簡單
先向系統要一塊兩倍大的記憶體 (也就是8個元素大小的記憶體)
把舊元素複製過去,然後才插入第5個元素。
剩下未使用的三個元素的空間呢?
目前就閒置著,這樣下次插入新元素時,就不需要重新要求記憶體空間。
直到這8個元素的空間都用完了
vector又會幹一樣的事,要求兩倍大的空間,然後將元素複製過去。
所以vector的記憶體使用率會一直在50%~100%之間擺盪
一般來說這種程度的記憶體浪費只是小事,畢竟現在記憶體又大又便宜。
可是像OGRE這種對效能極端要求的圖學引擎
就曾經被詬病說因為使用了太多STL容器
所以用了太多超過真正需要的記憶體。
如其他版友說的,已知最大元素個數的話,
先用reserve()保留好空間,可以避免浪費。
另外就是跨語言溝通,比方說C#/Java呼叫使用C++ funciton
那基本上就一定要使用原生陣列了。
※ 引述《QHsin (Q馨)》之銘言:
: 開發平台(Platform): (Ex: VC++, GCC, Linux, ...)
: Linux VC++
: 額外使用到的函數庫(Library Used): (Ex: OpenGL, ...)
: C++ Standard Library(C++標準程式庫)
: C++ Standard Template Library (STL)
: 問題(Question):
: 這應該算是剛入行沒多久的菜鳥問題。
: 主要是工作到現在,常常看到一些class寧可自行管理動態陣列,
: 而不喜歡直接使用vector,其中的原因自己研究不太出來,
: 所以想問問是不是有一些業界的相關經驗,導致有什麼不適合使用vector的狀況發生。
: 1.首先我碰過前輩寫的(目前不在公司問不到)系統,
: 建立的類別以目的來說,本身沒有可能移植到無法使用STL的環境。
: 2.第二是排除掉class使用vector的時候,
: 好像要定義operator=還是複製用的建構子其一,
: 但就連一般的字串、整數、浮點數這些複製上沒問題變數,也是用動態陣列自行管理。
: 3.連window.h的一些綁平台的功能,
: 都使用到class裡面做一些主要的管理(WinProc之類的),
: 同樣是STL的std::map也用了不少次,唯獨就幾乎不用vector。
: 4.程式碼裡面,沒有什麼特別vector無法實現的特殊操作。
: 個人的觀察,大概的訊息就像上面那樣,不知道純粹只是個人習慣,
: 還是vector有些不太適用的地方,想了解一下,否則每次使用vector的時候都抖抖的orz
: 以上,請各位前輩指教。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 58.99.21.163
推 EdisonX:我補一下一個誤解,不一定是二倍大,vc 的增長/縮減整個很怪 11/03 20:51
→ EdisonX:2 3 4 6 9 13 19 28 42 63 94 141 211 316 474 711 1066.. 11/03 20:51
→ EdisonX:然後即使增長做 realloc,"不一定"需要複製前面的東西,在於 11/03 20:58
→ EdisonX:realloc 後是否是同一份空間. 11/03 20:58
→ legnaleurc:它有自已的演算法,平均來說每個元素只會被複製一兩次 11/03 20:58
→ EdisonX:@legnaleurc :您上面的推文指的是 vc 的掌控策略是自己的? 11/03 21:00
推 Ebergies:另外 vector 由於保證資料連續所以其實跨語言也可以用 11/03 21:01
→ Ebergies:噢,當然別的語言傳不進來 vector 就是... 11/03 21:05
推 LPH66:VC 的看起來就是 1.5 倍而不是兩倍.... 11/03 22:51
→ LPH66:這樣的話使用率不會在 2/3 以下 相對的增長的次數就變多 11/03 22:51
推 EdisonX:疑!LPH66沒講我竟然沒發現是 1.5 / 0.44 !!真是感謝. 11/03 23:13
→ descent:已知最大元素個數的話, 為什麼不用 array 要用 vector? 11/04 14:02
→ linotwo:也許是因為 vector 有 push pop insert erase 等操作方式 11/04 15:04
→ Reylod:用stl container就不用自己寫= operator是嗎 11/04 15:22