首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > C语言 >

i++ 与 ++i 的效率哪个更高?解决思路

2012-08-30 
i++ 与 ++i 的效率哪个更高?今天我同学说 ++i 比 i++ 的效率更加高一些,因为他在某个地方看到严蔚敏老师是

i++ 与 ++i 的效率哪个更高?
今天我同学说 ++i 比 i++ 的效率更加高一些,因为他在某个地方看到严蔚敏老师是这么说的。我想问下csdn的大牛们,这是真的吗,能不能给一下解释了,小弟先在此谢过了。

[解决办法]
同意该说法
++i 不用生成临时变量而 i++要生成临时变量

[解决办法]
是滴,看生成的汇编代码就知道了
[解决办法]
以下纯属个人观点:
在语义一样的条件下一般认为++i比i++好,但经编译器优化后应该是一样的,这个我没有考证过,仅供参考!
[解决办法]
如果是内置类型如int单语句i++和++i没区别;
如果i是自定义的类型重载的后置++和前置++,有区别。
前置比后置效率高.
[解决办法]
看实际需要吧,没记错的话如果程序是:a=b++的话会先把b的值放进a里然后b再自己加1,如果是a=++b的话会先往b里加1再代进a里
[解决办法]
只有在必要时才使用后置操作符
因为前置操作需要做的工作更少,只需要加1后返回加1后的结果即可。而后置操作符则必须先保存操作数原来的值,以便返回未加1之前的值作为操作的结果。对于int对象和指针,编译器可优化掉这项额外工作。但是对于更多的复杂迭代器类型,这种额外工作可能会花费更大代价。因此,养成使用前置操作这个好习惯,就不必担心性能差异的问题。
[解决办法]
本质上.大多数编译器广商为了实现++i和i++的不同采用++i多用了一个寄存器变量的方法.
但是这不是C/C++标准范畴.讨论它意义不大:
你敢保证编译器广商都这么做吗?
[解决办法]
这个问题是分两种情况的:

1、对于内置数据类型,以现在的编译器的优化水平,前++和后++没区别的,这个可以通过看汇编代码证明

2、对于自定义数据类型,像STL,前++的效率要高于后++,所以STL中关于iterator都是前++的
[解决办法]
搭车问一下,VC6里的disassembly窗口里看到的就是编译生成的汇编么?
如下
a++;

Assembly code
0040102F   mov         eax,dword ptr [ebp-4]00401032   add         eax,100401035   mov         dword ptr [ebp-4],eax
[解决办法]
探讨
搭车问一下,VC6里的disassembly窗口里看到的就是编译生成的汇编么?
如下
a++;

Assembly code
0040102F mov eax,dword ptr [ebp-4]
00401032 add eax,1
00401035 mov dword ptr [ebp-4],eax


++a;

Assembly code
00401038 mov ecx,dword ptr [ebp-4]
0040103B add ecx,1
0040103E mov dword ptr [ebp-4],ecx



这样就是说两者一样么?

[解决办法]
简单的说:
i++(在c++中)在实现的时候,系统会产
生了一个local object class INT;
++i
INT INT::operator++()
{
*this=*this+1;
return *this;
}
i++
const INT INT::operator ++(int)
{
INT oldvalue=*this;
*this=*this+1;
return oldvalue
}

所以从效率上来说++i比i++来的更有效率
[解决办法]
怎么这两天跟++干上了?
下面这段话是我在帖子:《i=i++问题》中的回复。
我对汇编也不是很熟,我的理解是这样的:
i=0;
0041145E mov dword ptr [i (4171C0h)],0 //声明中的初始化
i=i++;
00411468 mov eax,dword ptr [i (4171C0h)] //将i值复制到寄存器
0041146D mov dword ptr [i (4171C0h)],eax //将寄存器中的值复制到i
//以上两步骤说明,程序的确先使用i值给等号左面的i赋值了
00411472 mov ecx,dword ptr [i (4171C0h)] //将i值复制到ecx寄存器
00411478 add ecx,1 //执行加一操作
0041147B mov dword ptr [i (4171C0h)],ecx //将结果复制给i

所以,在执行后缀加一运算时,编译后的程序的确是先使用欲加一的原始值给等号左边的变量赋值,然后再进行加一,其原因是无需保存后缀加一后的临时变量保存,以提高效率,这个往往在重载后的后缀加一操作符是无法实现的,因为重载后的后缀加一(或者减一)操作,我们都必须保存一个原始的临时变量,然后返回改变量的原始值,也因此,在stl中或者是任何重载了++/--操作符后,为了提高效率,尽量使用前缀操作符,这样避免了一次保存临时变量的操作,以提高效率。例如:

C/C++ code

... std::list<int>::iterator it=l.begin(); ++it;//效率高于it++; ...




[解决办法]
说到底其实不是效率的问题

就是后缀的++在一些情况下需要利用一个临时空间来保存自增前的值
尤其是自定义类型时 对后缀的++进行重载后,必定是如此的

而对应内部数据类型,如int long等,如果这个临时变量是不需要的,编译器自动会优化掉的
[解决办法]
一般来说++i 性能要高些,因为i++的意思,是在原有的i基础上加上1,表面上看假似乎在原有的内存空间上加上一,其实在加1的过程中是重新实例化一个内存空间,再把i加上1的值重定向到新实例化的内存空间中,等系统垃圾清理时会清理原先i的内存空间,如果i自加的次数多的话,这样会给系统带来很多的垃圾空间,而++i则是在自己的内存空间上自加,所以系统损耗少,最终我觉得i++比较好些
[解决办法]
对内置数据类型,很怀疑你的说法,他怎么优化呐?就说

int i =1;
int j= i++;
你认为如何优化才比
int j=++i 一样?

探讨
这个问题是分两种情况的:

1、对于内置数据类型,以现在的编译器的优化水平,前++和后++没区别的,这个可以通过看汇编代码证明

2、对于自定义数据类型,像STL,前++的效率要高于后++,所以STL中关于iterator都是前++的

[解决办法]
优化也要看出现在什么表达式中,如果单纯的
++i;
i++;
效果是一样的,因为没有表达式在后缀++操作前引用i的值,但是出现在一些表示中的时候就不一样了,i++必须保存一份i的拷贝给表达式使用,然后再进行++操作,所以要真说效率的话i++确实至少要多来一次脉冲
[解决办法]
简单的说:
i++(在c++中)在实现的时候,系统会产
生了一个local object class INT;
++i
INT INT::operator++()
{
*this=*this+1;
return *this;
}
i++
const INT INT::operator ++(int)
{
INT oldvalue=*this;
*this=*this+1;
return oldvalue
}

所以从效率上来说++i比i++更效率 但是对于单纯的 ++i 和 i++ 没什么区别 因为前而后置操作符则必须先保存操作数原来的值,以便返回未加1之前的值作为操作的结果。对于int对象和指针,编译器可优化掉这项额外工作

热点排行