【C/C++編程學習筆記】i ++ 和 ++ i,性能有區別嗎?

這是一個同學問的問題,據說是一個面試問題。

for(inti =0; i < n; i ++)

for(inti =0; i < n; ++ i)

兩個循環,在循環變量的更新上,一個是 i ++,一個是 ++ i。

性能有區別嗎?


首先,我要說,我不是很贊同這類“譚浩強式的問題”。在我看來,對這類問題如數家珍,和編程能力一點兒關係都沒有。

但是,對於一個對計算機感興趣的孩紙,時不時地研究一下這類“犄角旮旯”的問題,還是一件很有意思的事情。

對於 i ++ 和 ++ i 在語法上的區別,相信大家都瞭解。

 

i ++ 是先取值,後 ++。

如果 i = 0,則 int a = i ++ 以後,a 爲 0,i 爲 1。

 

而 ++ i 是先 ++,後取值。

如果 i = 0,則 int a = ++ i 以後,a 爲 1,i 爲 1。

 

如果我們將 i ++ 和 ++ i 想成是兩個函數,可以這樣理解。

i ++ 要先暫存 i 的初值,然後對 i 進行加 1 操作,之後返回之前暫存的 i 的初值。僞碼如下:

int j = i;

i= i +1;

return j;

 

而 ++ i,則不需要暫存 i 的初值,直接對 i 進行加 1 操作以後,返回新的 i 的值就好了。

i = i + 1;

return i;

 

這樣看,相信大家就能一目瞭然了,i ++ 的過程由於需要暫存 i 的初值,所以,理論上,性能耗費會更高一些。

因此,如果大家看一些“上古”的程序設計書籍(以 C 語言爲主),會提及,上面的 for 循環,用 ++ i 更好。


但是,在現代編程環境中,這一點性能偏差,完全可以忽略不計。

一方面,現代編譯器的優化,使得編譯器完全可以分析出,在上述 for 循環的 i ++ 以後,對 i 的結果並沒有進行賦值使用。從而,編譯器會進行優化,最後編譯出的邏輯,不進行上面所說的無用的暫存。

另一方面,即使使用不優化的編譯,有人統計過,對於現代計算機來說,循環次數要多達 10^47 次,纔可以產生人類可以察覺的性能差異。

10^47 是什麼概念?

整型可以存儲的數字規模是 10^9 這個量級。同學們可以在自己的計算機上嘗試一下,做一個循環 10^9 次的循環。每一次只是給一個整型賦值,看走完這個循環,需要多少時間?

以 C++ 爲例,大概就是這樣的一個程序:

對於大多數同學的計算機,相信這個循環需要的時間,是高於 1 秒鐘的。在我的計算機上,需要大概 1.3 秒。

就算只需要 1 秒鐘,10^47 是 10^9 的 10^38 倍。也就是,循環 10^47 次,大概需要 10^38 秒。

這是什麼概念呢?同學們可以用計算機計算一下,10^38 秒大概是 3*10^30 這麼多年。

因爲一天不過 60 * 60 * 24 =86400 秒;

一年不過 86400 * 365 = 3.1536 * 10^7 秒。

我查了一下,太陽系大概誕生於 64 億年前,即 6.4 * 10^9 年前。這麼算,現代計算機循環 10^47 這麼多操作的時間,億億個太陽系已經誕生了。

是億億,不是一億。用 3*10^30 除以 6.4*10^9,得到的結果,比一億個一億,還要大五萬倍左右。

所以,在通常使用的時候,i ++ 和 ++ i 的這個性能差距,如果在一些語言或者編譯環境(解析環境)中真的存在,也完全可以忽略不計。


那麼,在邏輯等價的情況下,應該使用 i ++ 還是 ++ i ?

在這種情況下,應該考慮的就是表意性。即哪種寫法最好理解?

可惜,表意性是一個主觀的事情,沒有客觀標準。因此,公說公有理,婆說婆有理。

或許這也就是爲什麼,在很多新興語言中,乾脆直接廢除掉 i ++ 或者 ++ i 這種語法吧。

i = i + 1,多清晰:)

 

寫完這篇小文,發現文中的計算,對於大家對數量級有一個直觀的理解很有幫助。

很多同學曾經問我類似這樣的問題:一個 O(n) 的算法,一秒鐘就跑完了,換成 O(n^2) 的算法,怎麼電腦沒反應了?

答案是:電腦在反應,但需要相當長的時間。

假設你的 n 是 10 萬左右。如果 O(n) 的算法用 1 秒鐘,O(n^2) 的算法就要用大概 10 萬秒鐘。(不嚴格,因爲 0.5n^2 也叫 O(n^2))

10 萬秒鐘,就是要一天多的時間。因爲,上文計算了,一天不過 86400 秒,即 8 萬多秒。所以,要真想看到 O(n^2) 算法的計算結果,耐心等着就好。

如果不想等這一天多的時間...... 那就是學習算法的意義了!

如果你想跟着小編一起學編程的話!
可以來我的C語言/C++編程學習交流俱樂部,【點擊進入】
還有(源碼,零基礎教程,項目實戰教學視頻),歡迎初學者和正在進階中的小夥伴們!  

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章