首页
社区
课程
招聘
[求助][求助]i++和i--的效率哪个高?为什么呢嚎?
发表于: 2009-4-1 07:23 8972

[求助][求助]i++和i--的效率哪个高?为什么呢嚎?

2009-4-1 07:23
8972
朋友问我2个for循环的语句的效率哪个高?如何判断?
for(int i = 0;   i<100 ; i++);
for(int i =100; i>0 ; i--);
我的解决方法就是把上面的语句反汇编,通过看汇编代码来判断这2个for循环效率的差异。
但比较下来,2个反汇编的汇编语句的条数是一样的,汇编语句有不一样,我想找汇编指令所占的机器时间又没找到。在网上搜索和问人,都说是i++和i--的差别,有说i--效率高的,也有说i++效率高的,但都说不出是为什么,所以请哪位朋友知道的,帮下忙,谢谢了

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (26)
雪    币: 231
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
都一样的吧.
2009-4-1 07:58
0
雪    币: 239
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
我认为关键在比较那个指令上
如是i--时,因为是和0比较,所以可使用
test eax,eax  ;直接寄存器比较,速度能加快吧
jnz XXXXXXX
这样的

使用i++时,因为是和100比较,所以要使用
cmp eax,100      ;和立即数比较,指令使用花的时间长
jnz xxxxxxxx
2009-4-1 09:02
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
谢谢上面2位的回答,我是在VS2005平台上反汇编的,下面是汇编代码
for(int i = 10; i> 0; i--)
55               push        ebp  
8B EC            mov         ebp,esp
81 EC CC 00 00 00 sub         esp,0CCh
53               push        ebx  
56               push        esi  
57               push        edi  
8D BD 34 FF FF FF lea         edi,[ebp-0CCh]
B9 33 00 00 00   mov         ecx,33h
B8 CC CC CC CC   mov         eax,0CCCCCCCCh
F3 AB            rep stos    dword ptr es:[edi]
     7:         for(int i = 10; i> 0; i--)
C7 45 F8 0A 00 00 00 mov         dword ptr [i],0Ah
EB 09            jmp         wmain+30h (411390h)
8B 45 F8         mov         eax,dword ptr [i]
83 E8 01         sub         eax,1
89 45 F8         mov         dword ptr [i],eax
83 7D F8 00      cmp         dword ptr [i],0
7E 02            jle         wmain+38h (411398h)    
8:         {
     9:         }
EB EF            jmp         wmain+27h (411387h)
    10:         return 0;
33 C0            xor         eax,eax
    11: }
5F               pop         edi  
5E               pop         esi  
5B               pop         ebx  
8B E5            mov         esp,ebp
5D               pop         ebp  
C3               ret      

        for(int i = 0; i < 10; i++)
55               push        ebp  
8B EC            mov         ebp,esp
81 EC CC 00 00 00 sub         esp,0CCh
53               push        ebx  
56               push        esi  
57               push        edi  
8D BD 34 FF FF FF lea         edi,[ebp-0CCh]
B9 33 00 00 00   mov         ecx,33h
B8 CC CC CC CC   mov         eax,0CCCCCCCCh
F3 AB            rep stos    dword ptr es:[edi]
     7:         for(int i = 0; i < 10; i++)
C7 45 F8 00 00 00 00 mov         dword ptr [i],0
EB 09            jmp         wmain+30h (411390h)
8B 45 F8         mov         eax,dword ptr [i]
83 C0 01         add         eax,1
89 45 F8         mov         dword ptr [i],eax
83 7D F8 0A      cmp         dword ptr [i],0Ah
7D 02            jge         wmain+38h (411398h)
     8:         {
     9:         }
EB EF            jmp         wmain+27h (411387h)
    10:         return 0;
33 C0            xor         eax,eax
    11: }
5F               pop         edi  
5E               pop         esi  
5B               pop         ebx  
8B E5            mov         esp,ebp
5D               pop         ebp  
C3               ret

汇编代码有不一样的地方,请问在哪可以查到像这样的汇编代码的机器时间啊?这样我就可以判断出哪个的效率高了
2009-4-1 09:18
0
雪    币: 7651
活跃值: (523)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
5
3楼的说法有点意思~
2009-4-1 09:37
0
雪    币: 207
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
i--更快些。
少一条cmp指令。
2009-4-1 09:37
0
雪    币: 200
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
额。lz要多大规模的计算啊,这个--和++有必要搞得这么清楚么
2009-4-1 09:51
0
雪    币: 8107
活跃值: (1955)
能力值: ( LV8,RANK:122 )
在线值:
发帖
回帖
粉丝
8
3楼正解, 做一些核心模块时,还是有效果的
2009-4-1 11:11
0
雪    币: 239
活跃值: (160)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
你贴的汇编代码是DEBUG模式下的,编译器没有优化,所以看不出区别,你自己用汇编来写一个,就知道区别在哪了。
2009-4-1 11:47
0
雪    币: 282
活跃值: (31)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
10
真要效率就别用C,直接写汇编
2009-4-1 11:54
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
应该是i--快
delphi后续的几个版本,用for i:=0 to 100时,有可能就编译成了 for i:=100 downto 0
2009-4-1 12:23
0
雪    币: 202
活跃值: (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
相差很小,不知道讨论这个还有什么意义?
2009-4-1 14:56
0
雪    币: 145
活跃值: (85)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
13
为软还开发什么VS2008,大家都学汇编算了。
2009-4-1 17:40
0
雪    币: 615
活跃值: (1202)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
14
2个for循环的效率是一样滴
2009-4-1 18:54
0
雪    币: 264
活跃值: (11)
能力值: ( LV9,RANK:250 )
在线值:
发帖
回帖
粉丝
15
编译的时候不要调试模式 之后再看看代码 求效率还是汇编..
2009-4-1 21:15
0
雪    币: 231
活跃值: (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qdk
16
请提供编译参数,有没有进行优化??
2009-4-2 01:35
0
雪    币: 82
活跃值: (10)
能力值: (RANK:210 )
在线值:
发帖
回帖
粉丝
17
从逻辑实现上面讲,sub有一个取2'的过程,执行要比add慢,现在新的处理器不知道怎么实现的了.

这个是可以克服的,比如初始化的时候找个地方存个负数,每次add即可.

代码上讲,判断zf比较容易,所以综合起来i--效率高些,不过,不是每个循环都可以这样转化的.
2009-4-2 02:04
0
雪    币: 263
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
18
我猜是i++快
貌似i--那个更容易branch prediction miss
2009-4-2 08:45
0
雪    币: 2067
活跃值: (82)
能力值: ( LV9,RANK:180 )
在线值:
发帖
回帖
粉丝
19
++快吧
祖先时代只有加法器
2009-4-2 09:10
0
雪    币: 126
活跃值: (179)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
20
智能编译器如果for循环内部没用到循环变量的时候,都会编译成递减循环.
递减循环少一次CMP指令.代码会短一点.
速度也会快一点点.大概一个CPU周期.但是现在一秒CPU可以运行N多次周期.这个完全不值得一提.
2009-4-2 09:15
0
雪    币: 209
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
Delphi 2007
原代码:
procedure TForm2.Button1Click(Sender: TObject);
var
  i,j: Integer;
begin
for i := 1 to 100 do
  Inc(j);
  ShowMessage(IntToStr(j));
end;


编译时没有打开优化选项:
Unit2.pas.30: for i := 1 to 100 do
0045BF87 C745F801000000   mov [ebp-$08],$00000001
Unit2.pas.31: Inc(j);
0045BF8E FF45F4           inc dword ptr [ebp-$0c]
0045BF91 FF45F8           inc dword ptr [ebp-$08]
Unit2.pas.30: for i := 1 to 100 do
0045BF94 837DF865         cmp dword ptr [ebp-$08],$65
0045BF98 75F4             jnz $0045bf8e
Unit2.pas.32: ShowMessage(IntToStr(j));
0045BF9A 8D55EC           lea edx,[ebp-$14]
0045BF9D 8B45F4           mov eax,[ebp-$0c]
0045BFA0 E8BFC7FAFF       call IntToStr
0045BFA5 8B45EC           mov eax,[ebp-$14]
0045BFA8 E8D310FDFF       call ShowMessage


编译时打开优化选项:
Unit2.pas.30: for i := 1 to 100 do
0045BF7C B864000000       mov eax,$00000064
Unit2.pas.31: Inc(j);
0045BF81 43               inc ebx
Unit2.pas.30: for i := 1 to 100 do
0045BF82 48               dec eax
0045BF83 75FC             jnz $0045bf81
Unit2.pas.32: ShowMessage(IntToStr(j));
0045BF85 8D55FC           lea edx,[ebp-$04]
0045BF88 8BC3             mov eax,ebx
0045BF8A E8D5C7FAFF       call IntToStr
0045BF8F 8B45FC           mov eax,[ebp-$04]
0045BF92 E8E910FDFF       call ShowMessage
2009-4-2 09:22
0
雪    币: 101
活跃值: (12)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
22
现代化编译器理论效率是一样的, 除非手动写汇编。
不过题目感觉没多大意义。。。
2009-4-2 09:47
0
雪    币: 251
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
肯定 ++i 和 --i 效率快啊.

后加加/后减减 ,需要保存原来的值到副本中,然后将相加后的结果再赋值到 i 中.

前加加/前减减 ,不用保存原来值的副本,直接加 1 ,效率更快.
2009-4-2 09:49
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24


我看到就想说这个来的

i++和i--的效率肯定没有++i和--i的效率高
2009-4-2 09:57
0
雪    币: 202
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
您的意思是直接运行,然后再看汇编代码?
2009-4-2 12:42
0
游客
登录 | 注册 方可回帖
返回
//