在循環語句中,for(i=0;i<n;i++)和for(i=0;i<n;++i)有什麼區別?
我同學有簡單地告訴我,i++的話要先copy出一個i然後賦值,用原來的i繼續其他運算,最後再把copy出來的i做個increment,然後返還給原來的i。
而++i直接在原來的i上做increment。結論:當n很大的時候,++i速度比i++快。比如語法上a = i++; 是等號右邊的變數賦值給左邊的變數,但是賦值應發生在所有運算之後。這就比較矛盾,如果用上訴理論就能解釋得清楚。請問他說的對嗎?
如果 i 是系統類型,兩者沒有性能區別。絕大多數編譯器可以生成同效率代碼。由於所謂的多餘複製的變數並沒有被用到(i++的返回值無人使用),所以編譯器優化之後跟++i等價。
兩者性能區別理論上存在於當 i 是一個自定義的類,並且這個類重載了++操作符,並且這個類重載「後增量」操作符時使用了值複製作為返回值的情況,在這種情況下,有時編譯器能優化掉多餘的複製,有時不能。所以++對於自定義對象類型來說會有題主所說的情況。不開優化,並沒有什麼不同
開啟優化,編譯器是不會在這種地方拖慢你的程序的一:i++ 和 ++i從Java的角度來說,這兩個沒有區別。(證據,生成的位元組碼一樣。)從C/C++的角度來說,++i可能更好一些,因為不用存儲一個中間變數。(但我懷疑這個是可以被編譯器優化掉的。)二:運算順序討論一個語句中如,i = i++ + i++。究竟++操作是何時發生的,對於C/C++語言可能沒有意義,因為是未定義行為,對於Java來說是有意義,因為Java明確定義了運算順序。
在C++里,假如i是int,那麼沒有任何不同,無論開不開優化,你沒有使用自增後的i值,編譯器根本就不會「複製」一個i。如果i是個自定義類型,又自定義了前綴和後綴++操作符,那自然是不一樣的。
習慣用++i,但我相信編譯器對此的優化,不會在意它的性能。
對於a = i++;那段,我不大清楚你的問題,不知道下面這樣說能不能幫你理解。
你說的「等號右邊的變數賦值給左邊的變數」,那既然是「值」,這個值也就可以來自於另外一個變數(假設是t),t保存了i自增前的值,然後把t返回給了左邊進行賦值操作。
把++理解成下面這個方法。int jiajia(int i)
{
int t = i;
i += 1;
return t;
}
我想說的是現在已經是2015年了,編譯器都發展了幾十年了連這點優化都做不到也好意思拿得出來?程序優化的重點應該放在項目的性能瓶頸上,而不是摳這種幾乎無意義的細枝末節。
再說了,如果你非覺得編譯器不可信非要寫成++i,那我可以告訴你把寫成 會更快(彙編可以少一個CMP指令,當然主流的編譯器基本都會自動幫你做這樣的優化)for(int i=0; i&
for(int i=n-1; i&>=0; --i)
所有支持++的語言中,按定義++i的速度一定大於等於i++
在循環語句中,for(i=0;i&
沒。
我同學有簡單地告訴我,i++的話要先copy出一個i然後賦值,用原來的i繼續其他運算,最後再把copy出來的i做個increment,然後返還給原來的i。
而++i直接在原來的i上做increment。
無依據的臆測。
比如語法上a = i++; 是等號右邊的變數賦值給左邊的變數,但是賦值應發生在所有運算之後。
錯。
====================================
做點正事,不要問沒有意義的問題。
現代程序設計不怎麼追求速度,通常認為代碼可讀性優先於程序效率。
即使要求效率也是從演算法和數據結構入手,
從for語句中挖掘速度無異於從牙縫裡找吃的希望吃的更飽些。
按C來說i++把i增加1,返回i增加前的值至於是先計算整個表達式還是先增加i應該是未定義的++i先把i加1,返回i的引用在for里i++和++i由於返回值沒有被使用,因此會被優化成一樣的結果
本來,這樣的問題我不會回答,心裡說「編譯器君掩面不語」後跳到下一個問題。但是沖著你的第一句話:「(這個問題估計1萬個程序員也不到1個能真正領悟)」。我忍不住進來跟你說,同學,你一定要成為一個萬里挑一的程序員啊。
for循環中不好說明,不妨假設有這樣一個表達式:
int i = 3;int k;k = ++i; //#1k = i++; //#2前置遞增運算符:對象遞增加一再使用
即:
/* #1等價於 */i = i+1; //i的值為4
k = i; //k 的值為4後置遞增運算符:創建一個臨時對象,將臨時對象替換調用原變數的位置,原變數+1
即:
/* #2等價於 */k = int(i); //int(i) 是一個臨時對象,值為4i = i+1; //i 的值為5也就是說後置遞增相比前置遞增會創建一個臨時對象int(i),使用臨時對象賦值給k,所以後置遞增會比前置遞增慢那麼一丟丟。學校里就講到++i先將i加一再運算,i++把原值運算後再加一,好low,突然感覺。。。。。。
只是人的習慣問題,就好比為什麼每個語言第一個程序叫hello world而不是hello monkey
加一段timer不就知道了么,我只記得老師說不管是++i還是i++都比i=i+1快,i++在n十分大的時候慢於++i,原理早忘了(或許應該查看下彙編)
測試一下
i++返回的是i本身的值,++i返回的是i+1的值,可以寫一個小程序測試一下就知道了。
這個問題把我們送回了80年代那個勒緊褲腰帶開發程序的日子,多兩三條代碼程序會慢到死嗎,我相信現在已經不是主要問題了,就算出現問題,那也是編譯器作者的問題,不是程序員的問題。
推薦閱讀:
※編寫彙編代碼最好的IDE是什麼?
※做了很久的項目,結果代碼全沒了是一種怎樣的體驗?
※在 GitHub 可以做什麼,用戶又習慣做些什麼?
※如何看待「初學者把自己新寫或寫的爛的項目放到 GitHub 就是浪費公共資源,給中國人丟臉」的言論?
※Microsoft Visual Studio可以用來開發ios和android么?