constructor 我喜歡翻譯成建構函式, 因為它本質的確是一個函式; destructor 我喜歡的翻譯是解構函式。當我寫 c 的時候, init() 我會取名 ctor(); destory() 我會取名為 dtor()。
在使用 std::vector 的時候, 會因為 vector 的容量變化而呼叫元素的解構函式, 這個負擔大不大呢?
vector 提供的 reserve 有沒有幫助?
我之前沒有細想這個問題。
由於我沒有執行 reserve, capacity() 一開始是 0, push c1 之後, vector 先配置 1 個元素的記憶體空間, copy ctor 發動, 複製 c1 到 vector[0], 目前總共有 c1, c2, vector[0] 總共 3 個 MyClass, capacity() 為 1。
push c2 之後, capacity() 空間不夠, 先配置 2 個元素的記憶體空間, 呼叫 copy ctor 複製 c2 以及在原本的 vector[0], 這時候共有 5 個 MyClass。
再來發動「原本的 vector[0]」 dtor, 現在的 MyClass 變為 4 個, 原本的有 1 個元素的記憶體空間被歸還。
在 vector 解構後, 會執行 4 次 MyClass dtor。
嚴格來說最開始的 ctor:2, 和最後的 dtor:2 不能算在 vector 頭上, 重新計算之後。
以 result 1 來看, 老實說我有點驚訝這個頻繁的次數, 以 result 2 結果來看就還好。
但如果用 v-1.push_back.cpp 的寫法, 因為 push_back 無法寫 my_class.push_back(); 得寫成 my_class.push_back(MyClass{});, 這寫法所有的開銷就得算在 vector 頭上了。
總開銷:
ctor: 2
copy ctor: 3
dtor: 5
和 result 1 一樣。
如果不想付出這麼頻繁的代價, 可以使用 vector<MyClass*> my_class; 指標的版本, 或是使用 reserve, reserve 可以減少發動 ctor, dtor 的次數。
c++11 之後有了 emplace_back(), 來看看這個新東西所帶來的效率改善。
直接寫 my_class.emplace_back() 就可在 vector[0] 插入一個 MyClass 物件。
push c1 時, 發動一次 ctor, push c2 時, c2 發動一次 ctor, 原本的 vector[0] 發動一次 copy ctor, 這時候總共有 3 個 MyClass, 之後 vector[0] 發動一次 dtor, 現在的 MyClass 總數為 2 個。
當 vector 解構之後, 發動 2 次 dtor。
總開銷:
ctor: 2
copy ctor : 1
dtor: 3
和 result 2. 的開銷一樣, 不過使用 emplace_back() 可是貨真價實的省下 2 個 ctor, 這使用了 variadic template 的技術, 我總算找到使用 variadic template 的原因了。
編譯: g++ -std=c++2a v.emplace_back.cpp -o v.emplace_back
emplace_back:
沒有留言:
張貼留言
使用 google 的 reCAPTCHA 驗證碼, 總算可以輕鬆留言了。
我實在受不了 spam 了, 又不想讓大家的眼睛花掉, 只好放棄匿名留言。這是沒辦法中的辦法了。留言的朋友需要有 google 帳號。