i++和++i的效率比较
简单的比较前缀自增运算符和后缀自增运算符的效率是片面的,因为存在很多因素影响这个问题的答案。
首先考虑内建数据类型的情况:如果自增运算表达式的结果没有被适用,而是仅仅简单地用于增加一元操作数,答案是明确的,前缀法和后缀法没有任何区别。编译器的处理都应该是相同的,很难想象得出有什么编译器实现可以别出心裁地在二者之间制造任何差异。
示例程序如下。
1 #include<stdio.h>
2
3 int main()
4 {
5 int i=0;
6 int x=0;
7
8 i++;
9 ++i;
10 x=i++;
11 x=++I;
12
13 return 0;
14 }
上面的代码在VISUAL C++6.0上编译得到的汇编如下: ;Line 5
mov DWORD PTR_i$[dbp],0 ; Line 6
mov DWORD PTR_i$[dbp],0 ; Line 8
mov eax,DWORD PTR_i$[ebp] add eax,1
mov DWORD PTR_i$[ebp],eax ; Line 9
mov eax,DWORD PTR_i$[ebp] add eax,1
mov DWORD PTR_i$[ebp],eax ; Line 10
mov edx,DWORD PTR_i$[ebp] mov DWORD PTR_x$[ebp],edx mov eax,DWORD PTR_i$[ebp] add eax,1
mov DWORD PTR_i$[ebp],eax ; Line 11
mov edx,DWORD PTR_i$[ebp] add eax,1
mov DWORD PTR_x$[ebp],edx mov eax,DWORD PTR_i$[ebp] mov DWORD PTR_i$[ebp],eax
代码段第8行和第9行生成的汇编代码分别对应Line8和Line9下面的汇编代码,可以看到3个步骤几乎完全一样。
代码段第10行和第11行生成的汇编代码分别对应Line10和Line11下面的汇编代码,可以看到都是5个步骤,只是在加1的先后顺序上有一些区别,效率也是完全一样的。 由此说明,考虑内建数据类型时,它们的效率差别不大(取出编译器优化的影响)。再考虑自定义数据类型(主要是指类)的情况。此时不需要再做很多汇编代码的分析,因为前缀是(++i)可以返回对象的应用,而后缀是(i++)必须返回对象的值,所以导致在大对象的时候产生了较大的复制开销,引起效率降低,因此使用自定义类型(注意不是指内建类型)的时候,应该尽可能地使用前缀式递增或递减。
因此,在内建数据类型的情况下,效率没有区别。 在自定义数据类型的情况下,++i的效率较高。
a1 += a2++;
执行过程:
a1 = a1 + a2;
++a2;
a1 += (++a2);
执行过程:
++a2;
a1= a1 + a2;
(++a1) += a2;
执行过程:
++a1;
a1 = a1 + a2;
(++a1) += a2++
执行过程:
++a1;
a1 = a1 + a2;
++a2;
(++a1) += (++a2);
执行过程:
++a1;
++a2;
a1 = a1 + a2;
(a1++) += (++a2);
错误:(a1++)不是左值