i++, ++i 和i=i+1究竟哪個快?
引子
以前學習C++時,被告知i++的速度要比i=+1快,而++i的速度又要比i++快。即在效率上有:++i > i++ > i=i+1。所以如果單單只是需要進行遞增時,用++i是最好的。但是某天我突然覺得:這三個運算的目的都是一樣,開銷按道理應該相同才對。難道編譯器如此之笨?就連這點優化都不會做?
運行時間測試(VS2008)
先用c#做了一遍:
static
private
void
Test()
{
int
counter = 0;
Stopwatch
timer = new
Stopwatch();
timer.Start();
for (int
i = 0; i < 2147483647; i++)
{
counter++;
}
timer.Stop();
Console.WriteLine("i++: " + timer.ElapsedMilliseconds);
timer.Reset();
counter=0;
timer.Start();
for (int
i = 0; i < 2147483647; ++i)
{
++counter;
}
timer.Stop();
Console.WriteLine("++i: " + timer.ElapsedMilliseconds);
timer.Reset();
counter=0;
timer.Start();
for (int
i = 0; i < 2147483647; i = i + 1)
{
counter=counter+1;
}
timer.Stop();
Console.WriteLine("i=i+1: "+timer.ElapsedMilliseconds);
Console.WriteLine();
}
從結果來看,幾乎沒有分別,每個算式都有機會獲得第一名。所以我覺得這3個算式對編譯器來說應該是沒有分別的。
用c++做了一遍
void
test()
{
int
elapTicks;
double
elapMilli;
clock_t
Begin, End;
int
counter = 0;
Begin = clock() * CLK_TCK; //start the timer
for(int
i=0; i<2147483647; i++) counter++;
End = clock() * CLK_TCK; //stop the timer
elapTicks = End - Begin; //the number of ticks from Begin to End
elapMilli = elapTicks/1000; //milliseconds from Begin to End
cout<<"i++: "<<elapMilli<<"\n";
counter=0;
Begin = clock() * CLK_TCK; //start the timer
for(int
i=0; i<2147483647; ++i) ++counter;
End = clock() * CLK_TCK; //stop the timer
elapTicks = End - Begin; //the number of ticks from Begin to End
elapMilli = elapTicks/1000; //milliseconds from Begin to End
cout<<"++i: "<<elapMilli<<"\n";
counter=0;
Begin = clock() * CLK_TCK; //start the timer
for(int
i=0; i<2147483647; i=i+1)counter=counter+1;
End = clock() * CLK_TCK; //stop the timer
elapTicks = End - Begin; //the number of ticks from Begin to End
elapMilli = elapTicks/1000; //milliseconds from Begin to End
cout<<"i=i+1: "<<elapMilli<<"\n\n";
}
結果也是類似。
結論
i++, ++i 和i=i+1的區別,應該只是純粹理論上的區別(即按照相應的表達算式進行編譯)。個人猜測對于以上3個表達式,編譯器在編譯之后應該生成一樣的語句。不過我不懂匯編,也不懂如何進一步深入測試。就此次測試的結果來看,3個表達式的時間開銷是一樣的(每次運行結果誤差應該是其他原因)。當然,此分析僅限于VS2008,有可能這3個語句在其他編譯器上的性能會有所不同。
歡迎指正。