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个语句在其他编译器上的性能会有所不同。
欢迎指正。