咱們常常使用for循環來遍歷東西,循環變量能夠前自增也能夠後自增,發現對遍歷結果沒啥影響,可是該如何選擇呢?算法
咱們應該儘可能使用前自增運算符而不是後自增運算符,即用 ++ Iter 代替 Iter++ 。 工具
爲何要這麼作,有什麼有實際價值?下面我會詳細解釋。性能
前綴和後綴形式之間的區別是衆所周知的。我但願它們內部結構的區別(告訴了咱們運算法則)你們也是清楚的。若是你有使用過運算符重載的話,確定已經意識到了。沒有用過的話,我在這兒簡單地解釋一下(用過運算符重載的能夠跳過下面關於運算符重載的例子)。單元測試
前自增運算符改變了對象的狀態並返回對象改變後的狀態,不須要建立臨時對象。下面是前自增運算符的例子:測試
MyOwnClass& operator++()
{優化
++meOwnField;this
return (*this);
}spa
後自增運算符也改變了對象的狀態可是返回的是對象改變前的狀態,而且須要建立一個臨時對象。下面是後自增運算符重載的例子:調試
MyOwnClass operator++(int)
{對象
MyOWnCLass tmp = *this;
++(*this);
return tmp;
}
看到上面這段代碼,你會發現有一個額外的操做,就是要建立一個臨時對象,在實踐中這點過重要了!
如今的編譯器作代碼優化的時候很是智能,若是沒有用處,是不會隨便建立臨時對象的。這就是爲何在發佈版中咱們很難發現 i++ 和 ++ i 的區別。
可是在調試模式下進行程序調試的時候就是另外一回事了,這時候你會看到性能上有很大差異。
舉個例子,在這篇文章中,有一些例子能夠估計調試版本中使用前自增和後自增運算符的代碼運行時間,咱們能夠看到使用後綴形式所用時間幾乎是前綴的四倍。
有人會說:」那又怎麼樣?反正發佈版都是同樣的。」,這種想法說對也對說不對也不對。一般咱們會花更多的時間作單元測試和調試程序,因此大多數時間都在調試版本下工做,誰也不想浪費時間在那兒等吧?
關於「對於迭代器,咱們是否應該用前自增運算符(++i)來代替後自增運算符(i++)?」這個問題,我想認真地回答: 「是的,真應該這麼作」。 你會發如今調試版本中速度大大提高。 若是迭代器很複雜的話,這麼作的好處更是顯而易見了。
這個錯誤是用靜態代碼分析工具 PVS-Studio 發現的,錯誤信息爲:V803 性能降低。 若是iter是迭代器的話,使用前自增運算符會更高效,使用 ++iter 代替 iter++.
無論咋樣,請用 ++ Iter 代替 Iter++,這是一個好的代碼習慣。