呵呵,这是C++中的一段代码,用vc++6.0编译的,debug版本.
int main(int argc, char* argv[])
{
int a=argc;
int j=a++;
printf("a=%d\n",a);
int c=++a;
printf("%d %d",a,c);
return 0;
}
反汇编代码如下:
Mov ecx,dword ptr[ebp-4;cx=a;
Mov dword ptr[ebp-1] ecx;=a
Mov edx,dword ptr[ebp-4];次访问a
Add edx,1
Mov dword ptr[ebp-4],;将a++的值存回a
这段代码,首先从内存中取a到寄存器,然后在存回内存j中。访问了两次内存。
然后再从内存中取出a,执行加法运算,两条mov,一条adx,共三条指令。
Mov ecx,dword ptr[ebp-4];a
Add ecx,1
Mov dword ptr [ebp-4],ecx;执行加法后结果存回a
Mov edx,dword ptr[ebp-4]次取a
Mov dword ptr[ebp-0Ch],edx;c=a;
这段代码,先计算a=a+1;其次将a赋值给c;
编代码整体性能是一样的,如果要是按参与运算顺序的话,那么毫无疑问,肯定是++a要快,因为他们之间要差一条指令,但这是微不足道的。因为在一个循环中,后面的指令终归还是要执行的。
对于这里的i++,从来没有在内存中创建一个副本,只是将他保存到了一个中间量寄存器中。
对于for循环,如果是release版本,编译器会对其进行许多优化,譬如将其转换为do-while结构,或者将for循环内的某些指令提取到for循环外来缩短for内指令数增加执行次数。
更重要的是,影响for循环性能的还有一个重要原因,那就是局部性的问题。如果访问问的数据或者指令没有出现在高速缓存中(第一次),或者数组分配的大小不合理(导致数据频繁的在高速缓存间换入换出),或者访问的步长太大(访问一个元素跳几个,间歇行访问)或者for循环内指令数太多,导致每一次循环都要好长时间。
如果是看字节码的话,也是这样,只不过在字节码中没有寄存器,所以只能使用dup指令将数据复制到计算栈顶,然后对这个复制版本进行操作。
|