黑马程序员技术交流社区

标题: 使用 ++i 真的比使用 i++ 具有更高的执行效率么? [打印本页]

作者: 鬼鬼    时间: 2014-3-17 15:11
标题: 使用 ++i 真的比使用 i++ 具有更高的执行效率么?
本帖最后由 鬼鬼 于 2014-3-17 19:49 编辑

很久之前学C++的时候不知道在哪里看见的这个说法,从那以后就形成了自增使用 ++i 的习惯,现在突然想起来这个问题,求证一下大家:
++i 真的比 i++ 具有更高的执行效率么?其中的原因又是什么?
作者: Max_骏    时间: 2014-3-17 15:24
看执行时间的话,二者一样,都是增量运算;但是作为赋值语句时:i++表示先赋值后加1;++i表示先加1再赋值;
例如:i=3,执行S=i++;后S=3,i=4。
         执行S=++i;后S=4,i=4。
我是这么理解的。。。。
作者: Dijkstra    时间: 2014-3-17 15:34
1、对于内置数据类型,以现在的编译器的优化水平,前++和后++没区别的,这个可以通过看汇编代码证明  2、对于自定义数据类型,像STL,前++的效率要高于后++,所以STL中关于iterator都是前++的
作者: mdb    时间: 2014-3-17 15:35
本帖最后由 mdb 于 2014-3-17 15:46 编辑

如果是int单语句i++和++i,现在的编译器的优化水平,基本没有什么差别...
作者: mdb    时间: 2014-3-17 16:28
关于单句i++与++i的区别
先写段试例代码,分别通过反汇编查看两者的代码有什么不同
  1.             private void Form1_Load(object sender, EventArgs e)
  2.         {
  3. // 后置++
  4.             int i = 0;
  5.             i++;
  6.             Console.WriteLine(i);
  7.         }
复制代码
运行程序后通过VS的反汇编窗口查看代码
关键部份代码
  1. 00000032  xor         edx,edx
  2. 00000034  mov         dword ptr [ebp-44h],edx
  3. 00000037  nop              
  4.             int i = 0;
  5. 00000038  xor         edx,edx
  6. 0000003a  mov         dword ptr [ebp-44h],edx
  7.             i++;
  8. 0000003d  inc         dword ptr [ebp-44h]
  9.             Console.WriteLine(i);
  10. 00000040  mov         ecx,dword ptr [ebp-44h]
  11. 00000043  call        75F727E4
  12. 00000048  nop              
复制代码
再写段前置++的代码
  1.         private void Form1_Load(object sender, EventArgs e)
  2.         {
  3. // 前置++
  4.             int i = 0;
  5.             ++i;
  6.             Console.WriteLine(i);
  7.         }
复制代码
反汇编后的代码
  1. 00000032  xor         edx,edx
  2. 00000034  mov         dword ptr [ebp-44h],edx
  3. 00000037  nop            
  4.             int i = 0;
  5. 00000038  xor         edx,edx
  6. 0000003a  mov         dword ptr [ebp-44h],edx
  7.             ++i;
  8. 0000003d  inc         dword ptr [ebp-44h]
  9.             Console.WriteLine(i);
  10. 00000040  mov         ecx,dword ptr [ebp-44h]
  11. 00000043  call        75F727E4
  12. 00000048  nop              
复制代码
由此可见,在i++和++i后汇编代码后都进行了一次inc的加一操作,所以两者效果是一样的。
--------------------------------------------------------------------------------------------------------------------------------
再看如果不是单句进行++,而是对变量进行一些计算,会有什么区别。
再写段简单的示例代码
后置++的代码
  1.         private void Form1_Load(object sender, EventArgs e)
  2.         {
  3.             int i = 0;
  4.             int j = 0;
  5.             j = 1 + i++; // 先进行运算再加一,J的结果是1,I的结果也是1
  6.             Console.WriteLine("i:" + i + " j:" + j);
  7.         }
复制代码
反汇编代码,关键部份
  1. 00000041  nop              
  2.             int i = 0;
  3. 00000042  xor         edx,edx
  4. 00000044  mov         dword ptr [ebp-44h],edx
  5.             int j = 0;
  6. 00000047  xor         edx,edx
  7. 00000049  mov         dword ptr [ebp-48h],edx
  8.             j = 1 + i++; // 先进行运算再加一,J的结果是1,I的结果也是1
  9. 0000004c  mov         eax,dword ptr [ebp-44h]
  10. 0000004f  mov         dword ptr [ebp-50h],eax
  11. 00000052  inc         dword ptr [ebp-44h]
  12. 00000055  mov         eax,dword ptr [ebp-50h]
  13. 00000058  inc         eax  
  14. 00000059  mov         dword ptr [ebp-48h],eax
  15.             Console.WriteLine("i:" + i + " j:" + j);
复制代码
再写段前置++的代码
  1.         private void Form1_Load(object sender, EventArgs e)
  2.         {
  3.             int i = 0;
  4.             int j = 0;
  5.             j = 1 + ++i; // i先加一然后再进行运算,J的结果是2,I的结果也是1
  6.             Console.WriteLine("i:" + i + " j:" + j);
  7.         }
复制代码
查看反汇编代码
  1. 00000041  nop              
  2.             int i = 0;
  3. 00000042  xor         edx,edx
  4. 00000044  mov         dword ptr [ebp-44h],edx
  5.             int j = 0;
  6. 00000047  xor         edx,edx
  7. 00000049  mov         dword ptr [ebp-48h],edx
  8.             j = 1 + ++i; // i先加一然后再进行运算,J的结果是2,I的结果也是1
  9. 0000004c  inc         dword ptr [ebp-44h]
  10. 0000004f  mov         eax,dword ptr [ebp-44h]
  11. 00000052  inc         eax  
  12. 00000053  mov         dword ptr [ebp-48h],eax
  13.             Console.WriteLine("i:" + i + " j:" + j);
复制代码
由此可见,j = 1 + i++这条语句的反汇编代码比j = 1 + ++i这条语句的反汇编代码多了两条汇编语句:
0000004c  mov         eax,dword ptr [ebp-44h]
0000004f  mov         dword ptr [ebp-50h],eax
i++比++i多了两条赋值语句,因为i++是先进行运算然后再自增,而++i是自增后再进行运算,i++由于要保留原值进行运算,所以i把原值赋给了[ebp-50h]这个地址指向的值






作者: 鬼鬼    时间: 2014-3-17 19:49
mdb 发表于 2014-3-17 16:28
关于单句i++与++i的区别
先写段试例代码,分别通过反汇编查看两者的代码有什么不同
运行程序后通过VS的反汇 ...

哦,明白啦,非常感谢!




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2