天天看點

采坑記錄-C++關于++i,i++,i=i+1,i+=1之間的差別于性能分析

++,+=,+之間性能對比

    • 内置類型
    • 自定義類型
        • i++和++i
    • i=i+1和i+=1
  • 起因:在leetcode上一道有關字元串的題,代碼流程與答案一樣,但是無法通過最後一個案例,顯示逾時,最後一個未通過的案例為一個長50000的string,經過調試,發現循環内有兩步為:str=str+String[i],将這一步改為+=就可以通過了。。。

内置類型

對于C++内置類型而言,如int,double等,++i,i++,i=i+1,i+=1這四種操作的效率是沒有差別的

在VS2019中,可以通過調試裡面的視窗,反彙編來檢視底層過程

自定義類型

對于類等自定義類型,差別就很明顯了。

i++和++i

i++是傳回原值本身,然後将變量+1

++i直接傳回加1的值

i++因為傳回了一個臨時變量,是以無法當左值,臨時變量隻能做右值

能否被指派不是區分左值與右值的依據。比如,C++的const左值是不可指派的;而作為臨時對象的右值可能允許被指派。左值與右值的根本差別在于是否允許取位址&運算符獲得對應的記憶體位址。
int i = 0;
int *p1 = &(++i); //正确
int *p2 = &(i++); //錯誤

++i = 1; //正确
i++ = 5; //錯誤
           

下面給出參考源碼

// 字首形式:
int& int::operator++() //這裡傳回的是一個引用形式,就是說函數傳回值也可以作為一個左值使用
{//函數本身無參,意味着是在自身空間内增加1的
  *this += 1;  // 增加
  return *this;  // 取回值
}

//字尾形式:
const int int::operator++(int) //函數傳回值是一個非左值型的,與字首形式的差别所在。
{//函數帶參,說明有另外的空間開辟
  int oldValue = *this;  // 取回值
  ++(*this);  // 增加
  return oldValue;  // 傳回被取回的值
}
           

i=i+1和i+=1

i=i+1相當于i++, 對于自定義類型而言,i=i+1由于臨時變量的存在在完整執行過程需要調用兩次構造函數

而i+=1和++i相同,因為傳回的引用是以隻需要1次構造即可

繼續閱讀