`
yeshaoting
  • 浏览: 684353 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

阅读更多

 

 

【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循环所需的指令数是一样的,二者执行效率相同.

分享到:
评论
21 楼 yeshaoting 2011-06-23  
johnson444 写道
围观围观围观围观中

围观?
都老贴了
20 楼 johnson444 2011-06-22  
围观围观围观围观中
19 楼 yeshaoting 2011-05-09  
pincs 写道
我感觉while做赋值快,for做输出快点

这个没有研究,有空看看 .
18 楼 pincs 2011-05-09  
我感觉while做赋值快,for做输出快点
17 楼 kakueiken 2011-05-06  
这年头VC6是古董了吧。那些古董游戏多知道用vs2008编译了。
16 楼 yeshaoting 2011-05-06  
h_rain 写道
强烈建议使用VC2003,VC2008等编译器,开启编译优化后再进行一下对比.
VC6实在是太旧了.

好吧...
对编译优化不太了解,了解后再进行对比吧.
15 楼 h_rain 2011-05-06  
强烈建议使用VC2003,VC2008等编译器,开启编译优化后再进行一下对比.
VC6实在是太旧了.
14 楼 yeshaoting 2011-04-30  
iamyuyingqiang 写道
楼主用过编译器优化过么?

这么高深的东西还不会。
还有待进一步提高~---
13 楼 iamyuyingqiang 2011-04-29  
楼主用过编译器优化过么?
12 楼 yeshaoting 2011-04-28  
<div class="quote_title">zhang247124629 写道</div>
<div class="quote_div">
<p>非常不错.学习啦..</p>
</div>
<p>哈哈...</p>
11 楼 zhang247124629 2011-04-28  
<p>非常不错.学习啦..</p>
10 楼 yeshaoting 2011-04-28  
爪哇岛岛主 写道
如果你理解迪米特法则(Low Of Demeter,LoD),或许你不会选择for

对这些法则了解不深...
学设计模式的时候也就学了点皮毛.
9 楼 爪哇岛岛主 2011-04-28  
如果你理解迪米特法则(Low Of Demeter,LoD),或许你不会选择for
8 楼 yeshaoting 2011-04-26  
pywepe 写道
这论坛都叫javaeye 能不说java吗

版块也没必要区分太细.
7 楼 pywepe 2011-04-26  
这论坛都叫javaeye 能不说java吗
6 楼 yeshaoting 2011-04-23  
skzr.org 写道
迷茫,标题指明是c语言,为什么后面变成了java的讨论了??

因为之前写了一篇【Java语言】while与for执行效率对比,然后想看看C里面的情况,就有了这篇.
后面的只是附加之笔.
见谅,我们可以继续这个话题.
不知道分析的是否全面....
5 楼 skzr.org 2011-04-23  
迷茫,标题指明是c语言,为什么后面变成了java的讨论了??
4 楼 yeshaoting 2011-04-23  
<div class="quote_title">chenqiangjsj 写道</div>
<div class="quote_div">
<p> </p>
<div class="quote_title"> 写道</div>
<div class="quote_div">public static int testFor(){<br> int i;<br> int sum = 0;<br> for (i = 0;i &lt; 100;i++){<br> sum = sum + i;<br> }<br> return sum;<br> }<br> public static int testWhile(){<br> int i;<br> int sum = 0;<br> i = 0;<br> while ( i &lt; 100){<br> sum = sum + i;<br> i ++;<br> }<br> return sum;<br> }</div>
<p>字节码指令为:</p>
<p> </p>
<pre name="code" class="java">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
</pre>
<p>
 完全一样</p>
</div>
<p>也是通过字节码得出来的结果呀.</p>
<p>我还以为有什么其他的理论呢.</p>
<p>不错~~</p>
3 楼 chenqiangjsj 2011-04-23  
<p> </p>
<div class="quote_title"> 写道</div>
<div class="quote_div">public static int testFor(){<br> int i;<br> int sum = 0;<br> for (i = 0;i &lt; 100;i++){<br> sum = sum + i;<br> }<br> return sum;<br> }<br> public static int testWhile(){<br> int i;<br> int sum = 0;<br> i = 0;<br> while ( i &lt; 100){<br> sum = sum + i;<br> i ++;<br> }<br> return sum;<br> }</div>
<p>字节码指令为:</p>
<p> </p>
<pre name="code" class="java">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
</pre>
<p>
 完全一样</p>
2 楼 yeshaoting 2011-04-18  
cectsky 写道
必须一样啊,在java中

兄台为何如此肯定.
给讲讲呗.

相关推荐

    各种经典算法+Java和C语言的两种实现

    - **优点**:C语言执行效率高,对内存管理有直接控制,适合编写系统级和嵌入式程序。 - **关键字和语法**:`main`函数、`for`和`while`循环、指针操作、结构体、数组等。 - **内存管理**:C语言需要手动分配和...

    蓝桥杯C语言历年真题与答案

    首先,C语言是计算机科学中的基础编程语言,它的语法简洁、执行效率高,特别适合进行系统级编程和算法实现。通过学习C语言,你可以深入理解计算机的工作原理,为学习其他高级语言打下坚实的基础。 在"蓝桥杯C语言...

    foreach、while、for性能比较

    3. **效率提升**:由于`foreach`是专门针对数组设计的循环结构,因此在内部实现了更高效的处理方式,避免了传统`for`和`while`循环中可能出现的冗余操作。 4. **语言特性**:在PHP这样的动态类型语言中,`foreach`...

    关于C语言的毕业论文题目100个.docx

    21. **Java和C语言的异同点**:对比两种语言的语法、执行效率和适用场景。 22. **C语言编程技术的分析研究**:分析C语言的各种编程技巧,如递归、循环、函数指针等。 23. **C语言循环语句的应用研究**:深入研究...

    C语言入门学习_上机100题

    C语言中的控制结构包括条件语句(if-else)、循环(for、while、do-while)以及开关语句(switch-case)。这些题目会训练初学者如何根据条件执行不同的代码块,以及如何用循环实现重复操作,这对理解程序流程控制至...

    C语言程序设计中for循环语句的教学设计探析.pdf

    在C语言程序设计教学中,for循环语句是学生在学习程序设计基础知识后接触到的一种循环控制结构,是实现程序重复执行的重要手段之一。它的教学设计直接关系到学生能否有效地掌握循环结构程序设计的思想和方法,进而...

    浅谈职业中专计算机C语言教学中循环应用

    2. **do-while循环**:与while循环不同,do-while循环会先执行一次循环体内的代码,然后再检查条件。这意味着即使条件一开始就不满足,循环体内的代码也会被执行至少一次。 ```c do { // 语句体(执行部分) } ...

    2000年到2007年c语言二级考试试题及答案word版

    3. **C语言知识点**:试题涵盖了C语言的关键知识点,如变量与数据类型、运算符与表达式、流程控制语句(如if、switch、for、while)、函数、数组、指针、结构体与联合体、文件操作等。 4. **编程技巧**:通过历年...

    dowhile语句 for语句 循环结构的嵌套PPT学习教案.pptx

    总的来说,do-while和for循环是C语言中控制循环的基本工具,它们提供了灵活的方式来重复执行代码块,根据不同的需求选择合适的循环结构可以极大地提高代码的效率和可读性。在编写循环时,要特别注意条件判断的位置、...

    C语言循环结构四步教学法.pdf

    C语言是一种广泛使用的高级编程语言,以其强大的表达能力、灵活性、高执行效率和良好的可移植性著称。在计算机程序设计领域,C语言经常作为入门语言,但其循环结构等概念对于初学者而言难度较大。循环结构是程序控制...

    C语言三种循环结构语句辨析.pdf

    为了加深理解,文章通过一个典型的程序实例,分别使用While、Do-While和For语句实现了相同的循环算法,对比分析了不同循环结构在表达和执行过程中的差异。最终,文章得出结论,For语句在书写上更为灵活,功能上更为...

    从英语学习自然过渡到C语言学习.pdf

    - 在英语中,句子的阅读顺序决定了理解的逻辑,而在C语言中,虽然书写顺序很重要,但执行顺序可能由控制结构(如if、for、while等)决定,这与英语的线性阅读方式有所不同。 3. **功能与结构**: - 英文文章由...

    C语言谭浩强循环控制PPT课件.pptx

    与`while`不同,`do...while`循环会先执行一次循环体,再检查条件表达式。这意味着`do...while`循环至少会执行一次。当条件不满足时,循环停止。同样,这里有一个使用`do...while`计算1到100的和的例子。对比`while`...

    c语言教程用于学习交流

    15. **C语言的扩展和C++的联系**:对比C语言与C++,理解C语言作为C++基础的重要性。 在学习过程中,通过实践编程项目和解决实际问题,你可以逐步提升C语言的编程技能。此外,与其他学习者交流,分享经验,也是提高...

    c8051f系列单片机用c语言精确延时的方法

    通过对比这三种循环语句的编译结果,可以发现`do-while`循环在生成汇编代码时更为简洁,而`while`和`for`循环在多数情况下具有相同的编译效率。 #### 双层循环的编译效率 当涉及到双层循环时,编译器的优化变得...

    浙江省C语言上机资料

    C语言是一种面向过程的、结构化的编程语言,它的语法简洁明了,执行效率高,适合编写系统软件和应用软件。C语言的关键元素包括变量、常量、数据类型、运算符、控制结构(如if-else、switch-case、for、while等)、...

    C语言32个关键字比对程序.zip_C语言

    8. `do`:与`while`一起构成do-while循环。 9. `double`:声明双精度浮点数类型变量。 10. `else`:与if语句配合,表示条件不成立时执行的代码块。 11. `enum`:定义枚举类型,一组命名的整数值。 12. `extern`:...

Global site tag (gtag.js) - Google Analytics