【C语言】while与for执行效率对比【转】

【C语言】while与for执行效率对比【转】

C语言编译环境: Microsoft Visual C++ 6.0(SP6)

测试程序

C代码  【C语言】while与for执行效率对比【转】
  1. #include "stdio.h"  
  2.   
  3. void forTest()  
  4. {  
  5.     int num = 1234;                 // 迭代次数  
  6.     long sum = 0;                   // 保存加法结果   
  7.   
  8.     for(int i=0;i<num;i++)       // 传统for循环写法  
  9.     {  
  10.         sum = sum + i;              // 计算结果  
  11.     }  
  12.   
  13.     printf("forTest:%d\n",sum);  
  14. }  
  15.   
  16. void whileTest()  
  17. {  
  18.     int num = 1234;                 // 迭代次数  
  19.     long sum = 0;                   // 保存加法结果  
  20.   
  21.     while((num--)>0)  
  22.     {  
  23.         sum = sum + num;            // 计算结果  
  24.     }  
  25.   
  26.     printf("whileTest:%d\n",sum);  
  27. }  
  28.   
  29.   
  30. void main()  
  31. {  
  32.     forTest();  
  33.     whileTest();  
  34. }  

汇编片段

whileTest()函数汇编后的指令:

--- D:\VC\ForWhile\ForWhile.cpp  ------------------------------------------------------------------------------------------

汇编指令代码  【C语言】while与for执行效率对比【转】
  1. 17:   void whileTest()  
  2. 18:   {  
  3. 0040D760   push        ebp  
  4. 0040D761   mov         ebp,esp  
  5. 0040D763   sub         esp,48h  
  6. 0040D766   push        ebx  
  7. 0040D767   push        esi  
  8. 0040D768   push        edi  
  9. 0040D769   lea         edi,[ebp-48h]  
  10. 0040D76C   mov         ecx,12h  
  11. 0040D771   mov         eax,0CCCCCCCCh  
  12. 0040D776   rep stos    dword ptr [edi]  
  13. 19:       int num = 1234;  
  14. 0040D778   mov         dword ptr [ebp-4],4D2h  
  15. 20:       long sum = 0;  
  16. 0040D77F   mov         dword ptr [ebp-8],0  
  17. 21:  
  18. 22:       while((num--)>0)  
  19. 0040D786   mov         eax,dword ptr [ebp-4]  
  20. 0040D789   mov         ecx,dword ptr [ebp-4]  
  21. 0040D78C   sub         ecx,1  
  22. 0040D78F   mov         dword ptr [ebp-4],ecx  
  23. 0040D792   test        eax,eax  
  24. 0040D794   jle         whileTest+41h (0040d7a1)  
  25. 23:       {  
  26. 24:           sum = sum + num;  
  27. 0040D796   mov         edx,dword ptr [ebp-8]  
  28. 0040D799   add         edx,dword ptr [ebp-4]  
  29. 0040D79C   mov         dword ptr [ebp-8],edx  
  30. 25:       }  
  31. 0040D79F   jmp         whileTest+26h (0040d786)  
  32. 26:  
  33. 27:       printf("whileTest:%d\n",sum);  
  34. 0040D7A1   mov         eax,dword ptr [ebp-8]  
  35. 0040D7A4   push        eax  
  36. 0040D7A5   push        offset string "whileTest:%d\n" (00422fac)  
  37. 0040D7AA   call        printf (0040d6e0)  
  38. 0040D7AF   add         esp,8  
  39. 28:   }  
  40. 0040D7B2   pop         edi  
  41. 0040D7B3   pop         esi  
  42. 0040D7B4   pop         ebx  
  43. 0040D7B5   add         esp,48h  
  44. 0040D7B8   cmp         ebp,esp  
  45. 0040D7BA   call        __chkesp (0040d6a0)  
  46. 0040D7BF   mov         esp,ebp  
  47. 0040D7C1   pop         ebp  
  48. 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  ------------------------------------------------------------------------------------------

汇编指令代码  【C语言】while与for执行效率对比【转】
  1. 4:    void forTest()  
  2. 5:    {  
  3. 0040D3F0   push        ebp  
  4. 0040D3F1   mov         ebp,esp  
  5. 0040D3F3   sub         esp,4Ch  
  6. 0040D3F6   push        ebx  
  7. 0040D3F7   push        esi  
  8. 0040D3F8   push        edi  
  9. 0040D3F9   lea         edi,[ebp-4Ch]  
  10. 0040D3FC   mov         ecx,13h  
  11. 0040D401   mov         eax,0CCCCCCCCh  
  12. 0040D406   rep stos    dword ptr [edi]  
  13. 6:        int num = 1234;  
  14. 0040D408   mov         dword ptr [ebp-4],4D2h  
  15. 7:        long sum = 0;  
  16. 0040D40F   mov         dword ptr [ebp-8],0  
  17. 8:  
  18. 9:        for(int i=0;i<num;i++)  
  19. 0040D416   mov         dword ptr [ebp-0Ch],0  
  20. 0040D41D   jmp         forTest+38h (0040d428)  
  21. 0040D41F   mov         eax,dword ptr [ebp-0Ch]  
  22. 0040D422   add         eax,1  
  23. 0040D425   mov         dword ptr [ebp-0Ch],eax  
  24. 0040D428   mov         ecx,dword ptr [ebp-0Ch]  
  25. 0040D42B   cmp         ecx,dword ptr [ebp-4]  
  26. 0040D42E   jge         forTest+4Bh (0040d43b)  
  27. 10:       {  
  28. 11:           sum = sum + i;  
  29. 0040D430   mov         edx,dword ptr [ebp-8]  
  30. 0040D433   add         edx,dword ptr [ebp-0Ch]  
  31. 0040D436   mov         dword ptr [ebp-8],edx  
  32. 12:       }  
  33. 0040D439   jmp         forTest+2Fh (0040d41f)  
  34. 13:  
  35. 14:       printf("forTest:%d\n",sum);  
  36. 0040D43B   mov         eax,dword ptr [ebp-8]  
  37. 0040D43E   push        eax  
  38. 0040D43F   push        offset string "forTest:%l\n" (00422e80)  
  39. 0040D444   call        printf (0040d6e0)  
  40. 0040D449   add         esp,8  
  41. 15:   }  
  42. 0040D44C   pop         edi  
  43. 0040D44D   pop         esi  
  44. 0040D44E   pop         ebx  
  45. 0040D44F   add         esp,4Ch  
  46. 0040D452   cmp         ebp,esp  
  47. 0040D454   call        __chkesp (0040d6a0)  
  48. 0040D459   mov         esp,ebp  
  49. 0040D45B   pop         ebp  
  50. 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  ------------------------------------------------------------------------------------------

汇编指令代码  【C语言】while与for执行效率对比【转】
  1. 4:    void forTest()  
  2. 5:    {  
  3. 0040D3F0   push        ebp  
  4. 0040D3F1   mov         ebp,esp  
  5. 0040D3F3   sub         esp,48h  
  6. 0040D3F6   push        ebx  
  7. 0040D3F7   push        esi  
  8. 0040D3F8   push        edi  
  9. 0040D3F9   lea         edi,[ebp-48h]  
  10. 0040D3FC   mov         ecx,12h  
  11. 0040D401   mov         eax,0CCCCCCCCh  
  12. 0040D406   rep stos    dword ptr [edi]  
  13. 6:        int num = 1234;  
  14. 0040D408   mov         dword ptr [ebp-4],4D2h  
  15. 7:        long sum = 0;  
  16. 0040D40F   mov         dword ptr [ebp-8],0  
  17. 8:  
  18. 9:        for(;(num--)>0;)  
  19. 0040D416   mov         eax,dword ptr [ebp-4]  
  20. 0040D419   mov         ecx,dword ptr [ebp-4]  
  21. 0040D41C   sub         ecx,1  
  22. 0040D41F   mov         dword ptr [ebp-4],ecx  
  23. 0040D422   test        eax,eax  
  24. 0040D424   jle         forTest+41h (0040d431)  
  25. 10:       {  
  26. 11:           sum = sum + num;  
  27. 0040D426   mov         edx,dword ptr [ebp-8]  
  28. 0040D429   add         edx,dword ptr [ebp-4]  
  29. 0040D42C   mov         dword ptr [ebp-8],edx  
  30. 12:       }  
  31. 0040D42F   jmp         forTest+26h (0040d416)  
  32. 13:  
  33. 14:       printf("forTest:%d\n",sum);  
  34. 0040D431   mov         eax,dword ptr [ebp-8]  
  35. 0040D434   push        eax  
  36. 0040D435   push        offset string "forTest:%l\n" (00422e80)  
  37. 0040D43A   call        printf (0040d6e0)  
  38. 0040D43F   add         esp,8  
  39. 15:   }  
  40. 0040D442   pop         edi  
  41. 0040D443   pop         esi  
  42. 0040D444   pop         ebx  
  43. 0040D445   add         esp,48h  
  44. 0040D448   cmp         ebp,esp  
  45. 0040D44A   call        __chkesp (0040d6a0)  
  46. 0040D44F   mov         esp,ebp  
  47. 0040D451   pop         ebp  
  48. 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循环所需的指令数是一样的,二者执行效率相同.

相关推荐