為什麼說 ++i 的效率比 i++ 高?

2021-03-02 程序設計及信息技術學習平臺

來源:公眾號【編程珠璣】

作者:守望先生

網站:https://www.yanbinghu.com

前言

不知道你是否聽說過++i比i++快的說法,真的如此嗎?

++i與i++的區別

這兩個表達式從我們初學程式語言的時候就會接觸到。前者是自增後取值,後者是取值後自增
我們看一個簡單的例子。

#include <iostream>
using namespace std;
int main()
{
    int a = 0;
    int b = 0;
    int c = a++;//int tmp = a;c=a;a = a + 1
    int d = ++b;//b = b + 1;d = b;
    cout<<"c="<<c<<";d="<<d<<endl;
    return 0;
}

運行結果:

c=0;d=1  

對於這個結果我們並不感到意外。

另外我們還注意到另外一個有意思的現象:

//來源:公眾號【編程珠璣】地址:https://www.yanbinghu.com
#include <iostream>
using namespace std;
int main()
{
    int a = 0;
    int b = 0;
    int *c = &(a++);
    int *d = &(++b);
    return 0;
}

編譯後報錯:

main.cpp:7:19: error: lvalue required as unary 『&』 operand
     int *c = &(a++);

說&作用於左值,也就是說a++的結果並非左值。但++b的結果是左值。

可簡單理解左值和右值:

運算符重載

在《運算符重載》一文中已經說到了運算符的重載,通過前面的例子也發現了,對於內置類型,前置自增返回對象的引用,而後置自增返回對象的原值(但非左值)。
基於上述原則,一個前置版本和後置版本的常見實現如下:

//來源:公眾號【編程珠璣】地址:https://www.yanbinghu.com
class Test
{
public:
    Test& operator++();//前置自增
    const Test operator++(int);//後置自增
private:
    int curPos; //當前位置
};
/*前置自增實現範式*/
Test& Test::operator++()
{
    ++curPos;      //自增
    return *this;  //取值
}
/*後置自增實現範式,為了與前置區分開,多了一個int參數,但從來沒用過*/
const Test Test::operator++(int)
{
    Test tmp = *this;  //取值
    ++curPos;             //自增
    return tmp;
}

仔細觀察後,我們發現前置自增,先自增,後返回原對象的對象;沒有產生任何臨時對象;而後置自增,先保存原對象,然後自增,最後返回該原臨時對象,那麼它就需要創建和銷毀,這樣一來,效率孰高孰低就很清楚了。

在不進行賦值的情況下,內置類型前置和後置自增的彙編都是一樣的呢!

void test()
{
  int i = 0;
  i++;
  //++i;
}

彙編:

push    rbp
mov     rbp, rsp
mov     DWORD PTR [rbp-4], 0
add     DWORD PTR [rbp-4], 1
nop
pop     rbp
ret

不過,賦值的情況下,並且不開啟編譯器優化,它們的彙編代碼還是有差別的,有興趣的可以試試。

總結

對於內置類型,前置和後置自增或者自減在編譯器優化的情況下,兩者並無多大差別,而對於自定義類型,如無特別需要,人們似乎更加偏愛前置自增或自減,因為後置自增常常會產生臨時對象。

但是,又能提高多少效率呢?

相關焦點

  • 為什麼說++i的效率比i++高?
    i++快的說法,真的如此嗎?++i與i++的區別這兩個表達式從我們初學程式語言的時候就會接觸到。前者是自增後取值,後者是取值後自增。我們看一個簡單的例子。可簡單理解左值和右值:運算符重載在《運算符重載》一文中已經說到了運算符的重載,通過前面的例子也發現了,對於內置類型,前置自增返回對象的引用,而後置自增返回對象的原值(但非左值)。
  • 為什麼說++i比i++效率高?
    i++快的說法,真的如此嗎?++i與i++的區別這兩個表達式從我們初學程式語言的時候就會接觸到。前者是自增後取值,後者是取值後自增。我們看一個簡單的例子。可簡單理解左值和右值:運算符重載在《運算符重載》一文中已經說到了運算符的重載,通過前面的例子也發現了,對於內置類型,前置自增返回對象的引用,而後置自增返回對象的原值(但非左值)。
  • 有趣的C語言語法:i++和++i的執行效率一樣高嗎?
    i++;++i;就C語言代碼來看,i++ 和 ++i 都只有一行,看起來似乎二者的執行效率一樣了?可見,j=i++; 計算機需要 4 條指令來解釋,比執行 k=++i; 多出了一條指令。多出的一條指令為:在對 i 執行自加操作之前,先保存 i 的當前值留作稍後使用(賦值為j)。這樣看來,似乎 ++i 的執行效率比 i++ 高一些?
  • iSuppli:iPad競爭者設計效率低而遠遠落後
    iSuppli發現,非蘋果平板產品的設計效率要明顯低於蘋果平板。本文引用地址:http://www.eepw.com.cn/article/122101.htm  iSuppli分析的產品包括16GBiPad和iPad2,摩託羅拉Xoom,黑莓Playbook,三星GalaxyTab,華碩EeePad和惠普Touchpad。
  • 抖音So funny Ya i ya i ya i ya i ya i ya i ya是什麼歌
    抖音So funny Ya i ya i ya i ya i ya i ya i ya是什麼歌?這首歌的歌詞中總是有著ya i ya i ya i ya i ya i ya的喃喃輕語,想必不少小夥伴都想知道是什麼歌曲吧!那麼下面一起來了解一下吧!
  • 抖音So funny Ya i ya i ya i ya i ya i ya i ya是什麼歌 懸溺...
    抖音So funny Ya i ya i ya i ya i ya i ya i ya是什麼歌 懸溺歌詞介紹  抖音So funny Ya i ya i ya i ya i ya i ya i ya歌曲介紹  懸溺  歌手:葛東琪  所屬專輯:第二街區(持續更新中,至10首)  作曲 : 葛東琪
  • 從自用到代理,iEnglish為什麼能火遍中國—iEnglish家長圈
    我想通過我們的分享和傳播,可以讓更多3-4線城市,甚至農村地區的孩子,享受和一線城市一樣的教育資源,甚至改變他們人生,我覺得這件事情非常值得有意義……以下是kailin老師的介紹和分享,從專業英語老師的角度分析為什麼要加入iEnglish事業!
  • 為什麼不能說「I smiled the sheriff」? - 英語教學法原著選讀120
    為什麼我們不能說I smiled the sheriff,卻能說I shot the sheriff呢?很簡單,因為smile是一個不及物動詞。所謂不及物動詞,就是指動作發生的時候,沒有對主語以外的任何人事物產生直接影響。
  • HTC HD2變谷歌旗艦 i-mobile i858評測
    另外我們也要對i858提出點小意見,為什麼又學HTC不加快門鍵了?難道為了省那麼點的塑料錢? #e#4.3寸夏普屏幕這部手機最震撼的地方就在於這塊4.3寸的巨大屏幕,解析度達到頂級的WVGA(480x800)的高水準,而且也是電容式觸控屏,只是由於系統的關心,暫時不支持多點觸控功能。
  • HR工作效率提升99%i人事
    ehr管理軟體有哪些?ehr管理軟體i人事致力於成為未來企業管理核心軟體。從自身定位來看,i人事有別於傳統管理軟體,而是將「人力資源+數位化」為核心貫穿始末,打通移動端與PC端數據流,幫助企業打造完整的人力資源管理體系閉環,未來的i人事必定是功能全面、交付友好、生態強大的企業管理軟體,也將一定會實現「讓中國HR都用上iHR」的美好願景。ehr管理軟體有哪些?
  • 英語非常重要的前元音 /i/和/i/ /i/Ship vs. /i/ Sheep
    Okay, and the sound we're comparing it to is the /i/ sound, /i/, okay.嘴型輕輕微笑,舌頭向上,在發這個音時,我們的嘴巴不是張成圓形的,而是幾乎閉合的,/i/。我們要和這個音對比的是/i/音,/i/。
  • 英語中的「I」為什麼要大寫
    各位有沒有想過,為什麼在英語寫作的時候,第一人稱單數的代詞I不管出現在句中什麼位置都一定要大寫呢?為什麼you,we,they,he,she之類的人稱代詞不用大寫呢?北京大學英語系教授辜正坤先生在央視《百家講壇》「當茶遇到咖啡」系列節目「中西語言文字與文化比較」一講中對上面這個問題有這樣的解讀:   "我們的人類的文化,包括中國的文化和西方的文化,有時候在口語當中容易表現出來,最簡單一個字就可以把問題說清楚。
  • i u üyw教師筆記,孩子多練發音方法,巧記i、ü標調規則
    u ü,聲母 y w,整體認讀音節 yi wu yu,把這三項內容放在一起學習,在讀音教學上效率高,會讀單韻母的音,再學讀聲母和整體認讀音節的發音,就簡單得多。但是這一課的學習內容比前一課 a o e 多,難度也高。孩子回家要多加練習朗讀,家長用與教師一致的科學方法示範、指導,才能讓孩子正確熟練地掌握髮音、區分聲韻母,和整體認讀音節,還要弄懂i 和 ü的標調規則。
  • 英語音標發音:前元音/i/ [i:] 和短元音/I/ [i]
    新東方網>英語>英語學習>口語>實用口語>正文英語音標發音:前元音/i/ [i:] 和短元音/I/ [i] 2012-12-11 16:38 來源:人人聽力 作者:
  • int i [ 4 ]={ i [ 2 ]=2 },神操作???
    別急,今天給大家帶來是Stackoverflow上的一個面試題,據說是美國福特公司嵌入式開發崗位的,這個真假我們就不深究了,我們需要關注的是題目本身,題目如下:#include<stdio.h>int main(void){    int i[4]={i[2]=2};    printf("%d %d %d %d\n",i[0],
  • 效率更高的是foreach還是for?為什麼?
    1、作為一名phper,for和foreach循環遍歷幾乎每天都在使用,那麼這兩種遍歷方式哪一種效率更高呢?2、效率高的原因是什麼呢?3、原理分別是什麼呢?0;$i<count($big_Array);$i++) { $i; } $end_For_Time = $this->microtime_float(); $for_Time = $end_For_Time - $start_For_Time; echo 'for循環遍歷耗時:'.
  • 海盜船AX1600i PSU評測:擁有準確的電源信號
    值得慶幸的是,Cybenetics的ETA效率標準具有AX1600i無法達到的更高級別(ETA-A ++)。在三到四年內,我們認為我們將開始看到能夠滿足該級別要求的PSU。雖然每個軌道都需要全數字轉換器,包括5VSB。Corsair與AX1600i的重要裡程碑是從矽轉換為氮化鎵FET。
  • 王一博同款Redmi K30i,高性價比5G手機,再降400元香不香?
    最近,Redmi K30i 直降 400 元,作為擁有 6GB + 128GB 內存的 5G 手機,價格從 1899 元降到 1499 元,這個價格讓整個手機行業隨之顫抖。想不到大內存的 5G 手機這麼快來到 1500 元檔,看來下半年 5G 手機價格還會繼續下滑,估計到明年初,百元機也會支持 5G 技術。
  • Everything I Do(I Do It For You
    歌詞:bryan adams everything i do(i do it for you)look into my eyes you will see what you mean to me search you heart search you soul and when you find me there you'll search
  • 從DM-p到DM-i,比亞迪再推插混是換了湯,還是換了藥?
    按理說純電動才是大趨勢,插混車型只是過度而已,為什麼在一些限牌不那麼嚴的城市,大家還是更願意選擇插混呢? 道理很簡單,能加油又有牌,價格可能還更會便宜。深層意思就是既沒有裡程焦慮,又有新能源福利,同時還能省錢,這便宜誰不想佔?