C++裸指標和智能指標的效率對比

來源:互聯網
上載者:User

C++裸指標和智能指標的效率對比

  1.unique_ptr與queue連用,unique_ptr的使用特點:不能使用拷貝建構函式,拷貝賦值函數,但是可以使用move建構函式和move賦值函數。

2.std::move的使用,可以將左值運算式強制轉化成為右值運算式

3. 重載new操作符調試記憶體使用量情況,因為心裡不是很放心(智能指標真的為我釋放了記憶體嗎?)所以嘗試了重寫new delete操作符。

4. 得到的結果是raw_ptr:unique_ptr:shared_ptr的效能是5:7:11,可見智能指標的效率還是相當誘人。

#include <iostream>#include <memory>#include <Windows.h>#include <queue>#include <Psapi.h>using namespace std;static size_ts_my_int_count = 0;const  intMAX_LOOP_ = 3000000;const int      NORMAL_FLAG = 0x12ff0101;const int   MY_INT_FLAG = 0x12ff0102;void* operator new(std::size_t size)throw(std::bad_alloc)//重寫new操作符為的是統計我們關心的記憶體配置{int addLen = sizeof(size_t);void * p = std::malloc(addLen + 4 + size) ;if (!p)throw std::bad_alloc() ;memcpy(p, &size, addLen);//標誌實際長度memcpy((char*)p + addLen, &NORMAL_FLAG, 4);//標誌類型,普通---0x12ff0101, 我自己的int---0x12ff0102, 我自己的char[]---0x12ff0103return ((char*)p + addLen + 4);}void* operator new(std::size_t size, int flag)throw(std::bad_alloc)// 對應於調用 “new(MY_INT_FLAG) int” 這樣所有我們關心的記憶體多可以被監視{int addLen = sizeof(size_t);void * p = std::malloc(addLen + 4 + size) ;if (!p)throw std::bad_alloc() ;if (flag == MY_INT_FLAG){s_my_int_count ++;//統計關心的記憶體申請次數}memcpy(p, &size, addLen);//標誌實際長度memcpy((char*)p + addLen, &flag, 4);//放置標誌位,標誌類型,普通---0x12ff0101, 我自己的int---0x12ff0102, 我自己的char[]---0x12ff0103return ((char*)p + addLen + 4);}void operator delete(void * q) throw(){void* p;int addLen = sizeof(size_t);p = (char*)q - addLen - 4;//還原原來的指標位置,p是真正的系統malloc出來的指標int flag;memcpy(&flag, (char*)p + addLen, 4);//得到標誌位if (flag == MY_INT_FLAG){//統計關心的記憶體釋放次數s_my_int_count --;}if (p)std::free(p) ;}void main(){queue<int*>  intQueue;int count = 0;count = 0;cout << "before push " << s_my_int_count << " int allocated"<< endl;LONGLONG start = GetTickCount();for (int i = 0; i < MAX_LOOP_; i ++){int* p = new(MY_INT_FLAG) int;intQueue.push(p);}cout << "after push " << s_my_int_count << " int allocated"<< endl;while (!intQueue.empty()){int* p = intQueue.front();intQueue.pop();delete p;//注意需要手動釋放count ++;}cout << "after pop " << s_my_int_count << " int allocated"<< endl;cout << "===================raw int ptr for " << count << "t" << GetTickCount() - start << endl;unique_ptr<int> q(new int);unique_ptr<int> r = move(q);// 編譯正確,r(q) 和 r = q則編譯失敗,因為unique_ptr已經不允許使用“拷貝建構函式”queue<unique_ptr<int>> intUniQueue;//因為unique_ptr沒有“拷貝建構函式”  copy-constructor//所以push()的參數不能是“左值”,左值會調用“拷貝建構函式”//只能是“右值”,右值則會調用“移動建構函式” move-constructor,  //std::move()函數可以強制將左值轉化成為右值count = 0;start = GetTickCount();cout << "before push " << s_my_int_count << " int allocated"<< endl;for (int i = 0; i < MAX_LOOP_; i ++){unique_ptr<int> p(new(MY_INT_FLAG) int);intUniQueue.push(std::move(p));//因為p不是“右值”,所以我們需要“顯式”的調用move將p強制轉為右值。}cout << "after push " << s_my_int_count << " int allocated"<< endl;while (!intUniQueue.empty()){unique_ptr<int> p = std::move(intUniQueue.front());//queue.front() 是一個左值引用,即queue.front()=2 合法。intUniQueue.pop();count ++;}cout << "after pop " << s_my_int_count << " int allocated"<< endl;cout << "===================int unique  ptr for " << count << "t" << GetTickCount() - start << endl;queue<shared_ptr<int>> intSharedQueue;count = 0;start = GetTickCount();cout << "before push " << s_my_int_count << " int allocated"<< endl;for (int i = 0; i < MAX_LOOP_; i ++){shared_ptr<int> p(new(MY_INT_FLAG) int);intSharedQueue.push(p);}cout << "after push " << s_my_int_count << " int allocated"<< endl;while (!intSharedQueue.empty()){auto p = intSharedQueue.front();intSharedQueue.pop();count ++;}cout << "after pop " << s_my_int_count << " int allocated"<< endl;cout << "===================int shared ptr for " << count << "t" << GetTickCount() - start << endl;}/*智能指標省去了我們釋放指標的精力,但是也需要一定的開銷。unique_ptr 的開銷相對於shared_ptr要小很多。如果一個資源每個時刻都只要有一個支配者,我們還是優先使用unique_ptr吧,效率會高很多。before push 0 int allocatedafter push 3000000 int allocatedafter pop 0 int allocated===================raw int ptr for 3000000      5375before push 0 int allocatedafter push 3000000 int allocatedafter pop 0 int allocated===================int unique  ptr for 3000000  7313before push 0 int allocatedafter push 3000000 int allocatedafter pop 0 int allocated===================int shared ptr for 3000000   11171請按任意鍵繼續. . .*/

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.