锁定老帖子 主题:【C语言】while与for执行效率对比
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-04-17
最后修改:2011-04-18
【C语言】while与for执行效率对比
C语言编译环境: Microsoft Visual C++ 6.0(SP6)
测试程序
#include "stdio.h" void forTest() { int num = 1234; // 迭代次数 long sum = 0; // 保存加法结果 for(int i=0;i<num;i++) // 传统for循环写法 { sum = sum + i; // 计算结果 } printf("forTest:%d\n",sum); } void whileTest() { int num = 1234; // 迭代次数 long sum = 0; // 保存加法结果 while((num--)>0) { sum = sum + num; // 计算结果 } printf("whileTest:%d\n",sum); } void main() { forTest(); whileTest(); }
汇编片段 whileTest()函数汇编后的指令: --- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
17: void whileTest() 18: { 0040D760 push ebp 0040D761 mov ebp,esp 0040D763 sub esp,48h 0040D766 push ebx 0040D767 push esi 0040D768 push edi 0040D769 lea edi,[ebp-48h] 0040D76C mov ecx,12h 0040D771 mov eax,0CCCCCCCCh 0040D776 rep stos dword ptr [edi] 19: int num = 1234; 0040D778 mov dword ptr [ebp-4],4D2h 20: long sum = 0; 0040D77F mov dword ptr [ebp-8],0 21: 22: while((num--)>0) 0040D786 mov eax,dword ptr [ebp-4] 0040D789 mov ecx,dword ptr [ebp-4] 0040D78C sub ecx,1 0040D78F mov dword ptr [ebp-4],ecx 0040D792 test eax,eax 0040D794 jle whileTest+41h (0040d7a1) 23: { 24: sum = sum + num; 0040D796 mov edx,dword ptr [ebp-8] 0040D799 add edx,dword ptr [ebp-4] 0040D79C mov dword ptr [ebp-8],edx 25: } 0040D79F jmp whileTest+26h (0040d786) 26: 27: printf("whileTest:%d\n",sum); 0040D7A1 mov eax,dword ptr [ebp-8] 0040D7A4 push eax 0040D7A5 push offset string "whileTest:%d\n" (00422fac) 0040D7AA call printf (0040d6e0) 0040D7AF add esp,8 28: } 0040D7B2 pop edi 0040D7B3 pop esi 0040D7B4 pop ebx 0040D7B5 add esp,48h 0040D7B8 cmp ebp,esp 0040D7BA call __chkesp (0040d6a0) 0040D7BF mov esp,ebp 0040D7C1 pop ebp 0040D7C2 ret --- No source file ------------------------------------------------------------------------------------------------------- 分析: 0040D760~0040D776: 保存栈现场 总共10条指令 0040D778: 迭代次数 总共1条指令 0040D77F: 保存加法结果 总共1条指令 0040D786~0040D79F: while循环 总共10条指令 0040D7A1~0040D7AF: 打印结果 总共5条指令 0040D7B2~0040D7C2: 恢复栈现场 总共9条指令 合计: 36条指令
forTest()函数汇编后的指令: --- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
4: void forTest() 5: { 0040D3F0 push ebp 0040D3F1 mov ebp,esp 0040D3F3 sub esp,4Ch 0040D3F6 push ebx 0040D3F7 push esi 0040D3F8 push edi 0040D3F9 lea edi,[ebp-4Ch] 0040D3FC mov ecx,13h 0040D401 mov eax,0CCCCCCCCh 0040D406 rep stos dword ptr [edi] 6: int num = 1234; 0040D408 mov dword ptr [ebp-4],4D2h 7: long sum = 0; 0040D40F mov dword ptr [ebp-8],0 8: 9: for(int i=0;i<num;i++) 0040D416 mov dword ptr [ebp-0Ch],0 0040D41D jmp forTest+38h (0040d428) 0040D41F mov eax,dword ptr [ebp-0Ch] 0040D422 add eax,1 0040D425 mov dword ptr [ebp-0Ch],eax 0040D428 mov ecx,dword ptr [ebp-0Ch] 0040D42B cmp ecx,dword ptr [ebp-4] 0040D42E jge forTest+4Bh (0040d43b) 10: { 11: sum = sum + i; 0040D430 mov edx,dword ptr [ebp-8] 0040D433 add edx,dword ptr [ebp-0Ch] 0040D436 mov dword ptr [ebp-8],edx 12: } 0040D439 jmp forTest+2Fh (0040d41f) 13: 14: printf("forTest:%d\n",sum); 0040D43B mov eax,dword ptr [ebp-8] 0040D43E push eax 0040D43F push offset string "forTest:%l\n" (00422e80) 0040D444 call printf (0040d6e0) 0040D449 add esp,8 15: } 0040D44C pop edi 0040D44D pop esi 0040D44E pop ebx 0040D44F add esp,4Ch 0040D452 cmp ebp,esp 0040D454 call __chkesp (0040d6a0) 0040D459 mov esp,ebp 0040D45B pop ebp 0040D45C ret --- No source file ------------------------------------------------------------------------------------------------------- 分析: 0040D3F0~0040D406: 保存栈现场 总共10条指令 0040D408: 迭代次数 总共1条指令 0040D40F: 保存加法结果 总共1条指令 0040D416~0040D439: for循环 总共12条指令 0040D43B~0040D449: 打印结果 总共5条指令 0040D44C~0040D45C: 恢复栈现场 总共9条指令 合计: 38条指令
程序中二个方法语句区别在于一个是for循环,一个是while循环. 对应于,查看到上述二段汇编指令段while循环比for循环少了二条指令.
程序中for循环用的是传统写法,做下更改将for(int i=0;i<num;i++)改为for(;(num--)>0;),其汇编指令为: --- D:\VC\ForWhile\ForWhile.cpp ------------------------------------------------------------------------------------------
4: void forTest() 5: { 0040D3F0 push ebp 0040D3F1 mov ebp,esp 0040D3F3 sub esp,48h 0040D3F6 push ebx 0040D3F7 push esi 0040D3F8 push edi 0040D3F9 lea edi,[ebp-48h] 0040D3FC mov ecx,12h 0040D401 mov eax,0CCCCCCCCh 0040D406 rep stos dword ptr [edi] 6: int num = 1234; 0040D408 mov dword ptr [ebp-4],4D2h 7: long sum = 0; 0040D40F mov dword ptr [ebp-8],0 8: 9: for(;(num--)>0;) 0040D416 mov eax,dword ptr [ebp-4] 0040D419 mov ecx,dword ptr [ebp-4] 0040D41C sub ecx,1 0040D41F mov dword ptr [ebp-4],ecx 0040D422 test eax,eax 0040D424 jle forTest+41h (0040d431) 10: { 11: sum = sum + num; 0040D426 mov edx,dword ptr [ebp-8] 0040D429 add edx,dword ptr [ebp-4] 0040D42C mov dword ptr [ebp-8],edx 12: } 0040D42F jmp forTest+26h (0040d416) 13: 14: printf("forTest:%d\n",sum); 0040D431 mov eax,dword ptr [ebp-8] 0040D434 push eax 0040D435 push offset string "forTest:%l\n" (00422e80) 0040D43A call printf (0040d6e0) 0040D43F add esp,8 15: } 0040D442 pop edi 0040D443 pop esi 0040D444 pop ebx 0040D445 add esp,48h 0040D448 cmp ebp,esp 0040D44A call __chkesp (0040d6a0) 0040D44F mov esp,ebp 0040D451 pop ebp 0040D452 ret --- No source file ------------------------------------------------------------------------------------------------------- 0040D3F0~0040D406: 保存栈现场 总共10条指令 0040D408: 迭代次数 总共1条指令 0040D40F: 保存加法结果 总共1条指令 0040D416~0040D42F: for循环 总共10条指令 0040D431~0040D43F: 打印结果 总共5条指令 0040D442~0040D452: 恢复栈现场 总共9条指令 合计: 36条指令
由此可见,for循环习惯写法for(int i=0;i<num;i++)执行效率低于for(;(num--)>0;)写法,而for(;(num--)>0;)写法执行效率与while((num--)>0)相同. 因此,一棒子打死说for循环执行效率比while循环慢是不对的.
【Java语言】while与for执行效率对比: 经查看class文件反编译指令发现,Java中执行for循环与执行while循环所需的指令数是一样的,二者执行效率相同.
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-04-18
必须一样啊,在java中
|
|
返回顶楼 | |
发表时间:2011-04-18
cectsky 写道 必须一样啊,在java中
兄台为何如此肯定. 给讲讲呗. |
|
返回顶楼 | |
发表时间:2011-04-23
最后修改:2011-04-23
写道
public static int testFor(){
int i; int sum = 0; for (i = 0;i < 100;i++){ sum = sum + i; } return sum; } public static int testWhile(){ int i; int sum = 0; i = 0; while ( i < 100){ sum = sum + i; i ++; } return sum; } 字节码指令为:
public static int testFor(); Code: 0: iconst_0 1: istore_1 2: iconst_0 3: istore_0 4: goto 14 7: iload_1 8: iload_0 9: iadd 10: istore_1 11: iinc 0, 1 14: iload_0 15: bipush 100 17: if_icmplt 7 20: iload_1 21: ireturn public static int testWhile(); Code: 0: iconst_0 1: istore_1 2: iconst_0 3: istore_0 4: goto 14 7: iload_1 8: iload_0 9: iadd 10: istore_1 11: iinc 0, 1 14: iload_0 15: bipush 100 17: if_icmplt 7 20: iload_1 21: ireturn 完全一样 |
|
返回顶楼 | |
发表时间:2011-04-23
chenqiangjsj 写道
写道
public static int testFor(){
int i; int sum = 0; for (i = 0;i < 100;i++){ sum = sum + i; } return sum; } public static int testWhile(){ int i; int sum = 0; i = 0; while ( i < 100){ sum = sum + i; i ++; } return sum; } 字节码指令为:
public static int testFor(); Code: 0: iconst_0 1: istore_1 2: iconst_0 3: istore_0 4: goto 14 7: iload_1 8: iload_0 9: iadd 10: istore_1 11: iinc 0, 1 14: iload_0 15: bipush 100 17: if_icmplt 7 20: iload_1 21: ireturn public static int testWhile(); Code: 0: iconst_0 1: istore_1 2: iconst_0 3: istore_0 4: goto 14 7: iload_1 8: iload_0 9: iadd 10: istore_1 11: iinc 0, 1 14: iload_0 15: bipush 100 17: if_icmplt 7 20: iload_1 21: ireturn 完全一样 也是通过字节码得出来的结果呀. 我还以为有什么其他的理论呢. 不错~~ |
|
返回顶楼 | |
发表时间:2011-04-23
迷茫,标题指明是c语言,为什么后面变成了java的讨论了??
|
|
返回顶楼 | |
发表时间:2011-04-23
skzr.org 写道 迷茫,标题指明是c语言,为什么后面变成了java的讨论了??
因为之前写了一篇【Java语言】while与for执行效率对比,然后想看看C里面的情况,就有了这篇. 后面的只是附加之笔. 见谅,我们可以继续这个话题. 不知道分析的是否全面.... |
|
返回顶楼 | |
发表时间:2011-04-26
这论坛都叫javaeye 能不说java吗
|
|
返回顶楼 | |
发表时间:2011-04-26
pywepe 写道 这论坛都叫javaeye 能不说java吗
版块也没必要区分太细. |
|
返回顶楼 | |
发表时间:2011-04-28
如果你理解迪米特法则(Low Of Demeter,LoD),或许你不会选择for
|
|
返回顶楼 | |