引言

  大家都知道每种循环对应的效率是不同的,书中都说在循环中使用减法的效率是比加法的效率高的,具体情况是怎么样,我们将详细列出各循环的执行效率问题。本文通过查看汇编代码比较各循环的效率以及i++,++i,i--,--i在循环中使用的效率问题,仅供抛砖引玉,测试平台为intel i5 4440,编译器为gcc-4.8.2

测试代码1

  此段代码我们主要测试在i--,--i,i++,++i的情况下,for循环、dowhile循环、while循环之间的执行效率情况

 #include <stdio.h>

 /* 用于测试i--的while,for,dowhile循环情况 */
void minus1 (void)
{
int i = ; /* i-- while循环 */
while (i--)
; i = ; /* i-- dowhile循环 */
do
;
while (i--); /* i-- for循环 */
for (i = ; i != ; i--)
;
} /* 用于测试--i的while,for,dowhile循环情况 */
void minus (void)
{
int i = ; /* --i while循环 */
while (--i)
; i = ; /* --i dowhile循环 */
do
;
while (--i); /* --i for循环 */
for (i = ; i != ; --i)
;
} /* 用于测试i++的while,for,dowhile循环情况 */
void plus1 (void)
{
int i = ; /* i++ while循环 */
while (i++ < )
; i = ; /* i++ dowhile循环 */
do
;
while (i++ < ); /* i++ for循环 */
for (i = ; i < ; i++)
;
} /* 用于测试++i的while,for,dowhile循环情况 */
void plus (void)
{
int i = ; /* ++i while循环 */
while (++i < )
; i = ; /* ++i dowhile循环 */
do
;
while (++i < ); /* ++i for循环 */
for (i = ; i < ; ++i)
;
} int main (int argc, char * argv[])
{
return ;
}

测试代码1所生成的汇编代码如下:

 #include <stdio.h>

 void minus1 (void)
{
4004ed: push %rbp
4004ee: e5 mov %rsp,%rbp
int i = ;
4004f1: c7 fc 0a movl $0xa,-0x4(%rbp)      # i = while (i--)   # while (i--)
4004f8: nop   # 空指令
4004f9: 8b fc mov -0x4(%rbp),%eax # eax = i 主循环
4004fc: 8d ff lea -0x1(%rax),%edx # edx = rax - (rax的低32位为eax) 主循环
4004ff: fc mov %edx,-0x4(%rbp) # i = edx 主循环
: c0 test %eax,%eax # 等同于(i & i), 如果i不等于0,则结果也不为0 主循环
: f3 jne 4004f9 <minus1+0xc> # 不等于0则跳转至4004f9 主循环
; i = ;
: c7 fc 0a movl $0xa,-0x4(%rbp) # i = do
;
while (i--); # do ... while (i--);
40050d: 8b fc mov -0x4(%rbp),%eax # eax = i 主循环
: 8d ff lea -0x1(%rax),%edx # edx = rax - (rax的低32位为eax) 主循环
: fc mov %edx,-0x4(%rbp) # i = edx 主循环
: c0 test %eax,%eax # 等同于(i & i), 如果i不等于0,则结果也不为0 主循环
: f3 jne 40050d <minus1+0x20> # 不等于0则跳转至40050d 主循环 for (i = ; i != 0; i--) # for (i = 10; i != 0; i--)
40051a: c7 fc 0a movl $0xa,-0x4(%rbp) # i =
: eb jmp <minus1+0x3a> # 跳转至400527
: 6d fc subl $0x1,-0x4(%rbp) # i = i - 主循环
: 7d fc cmpl $0x0,-0x4(%rbp) # i与0进行比较    主循环
40052b: f6 jne <minus1+0x36> # 比较结果不等于0则跳转至400523      主循环
;
} void minus (void)
{
40052f: push %rbp
: e5 mov %rsp,%rbp
int i = ;
: c7 fc 0a movl $0xa,-0x4(%rbp) while (--i) # while (--i)
40053a: 6d fc subl $0x1,-0x4(%rbp) # i = i -                  主循环
40053e: 7d fc cmpl $0x0,-0x4(%rbp) # i与0比较                  主循环
: f6 jne 40053a <minus+0xb> # 比较结果不等于0则跳转至40053a        主循环
; i = ;
: c7 fc 0a movl $0xa,-0x4(%rbp) do
;
while (--i); # do ... while (--i);
40054b: 6d fc subl $0x1,-0x4(%rbp) # i = i -    主循环
40054f: 7d fc cmpl $0x0,-0x4(%rbp) # i与0比较      主循环
: f6 jne 40054b <minus+0x1c> # 比较结果不等于0则跳转至40054b 主循环 for (i = ; i != 0; --i) # for (i = 10; i != 0; --i)
: c7 fc 0a movl $0xa,-0x4(%rbp) # i =
40055c: eb jmp <minus+0x33> # 跳转至400562
40055e: 6d fc subl $0x1,-0x4(%rbp) # i = i -    主循环
: 7d fc cmpl $0x0,-0x4(%rbp) # i与0比较 主循环
: f6 jne 40055e <minus+0x2f> # 比较结果不等于0则跳转至40055e 主循环
;
} void plus1 (void)
{
40056a: push %rbp
40056b: e5 mov %rsp,%rbp
int i = ;
40056e: c7 fc movl $0x0,-0x4(%rbp) while (i++ < ) # while (i++ < )
: nop
: 8b fc mov -0x4(%rbp),%eax # eax = i    主循环
: 8d lea 0x1(%rax),%edx # edx = rax + (rax的低32位为eax)      主循环
40057c: fc mov %edx,-0x4(%rbp) # i = edx      主循环
40057f: f8 cmp $0x9,%eax # eax与9比较      主循环
: 7e f2 jle <plus1+0xc> # 比较结果不成立则跳转至400576      主循环
; i = ;
: c7 fc movl $0x0,-0x4(%rbp) do
;
while (i++ < ); # while (i++ < 10);
40058b: 8b fc mov -0x4(%rbp),%eax # eax = i 主循环
40058e: 8d lea 0x1(%rax),%edx # edx = rax + (rax的低32位为eax) 主循环
: fc mov %edx,-0x4(%rbp) # i = edx 主循环
: f8 cmp $0x9,%eax # eax与9比较 主循环
: 7e f2 jle 40058b <plus1+0x21> # 比较结果不成立则跳转至40058b 主循环 for (i = ; i < 10; i++) # for (i = 0; i < 10; i++)
: c7 fc movl $0x0,-0x4(%rbp) # i =
4005a0: eb jmp 4005a6 <plus1+0x3c> # 跳转至4005a6
4005a2: fc addl $0x1,-0x4(%rbp) # i = i + 主循环
4005a6: 7d fc cmpl $0x9,-0x4(%rbp) # i与9比较 主循环
4005aa: 7e f6 jle 4005a2 <plus1+0x38> # 比较结果不成立则跳转至4005a2 主循环
;
} void plus (void)
{
4005ae: push %rbp
4005af: e5 mov %rsp,%rbp
int i = ;
4005b2: c7 fc movl $0x0,-0x4(%rbp) while (++i < ) # while (++i < )
4005b9: fc addl $0x1,-0x4(%rbp) # i = i + 主循环
4005bd: 7d fc cmpl $0x9,-0x4(%rbp) # i与9比较 主循环
4005c1: 7e f6 jle 4005b9 <plus+0xb> # 比较结果不成立则跳转至4005b9 主循环
; i = ;
4005c3: c7 fc movl $0x0,-0x4(%rbp) do
;
while (++i < ); # while (++i < 10);
4005ca: fc addl $0x1,-0x4(%rbp) # i = i + 主循环
4005ce: 7d fc cmpl $0x9,-0x4(%rbp) # i与9比较 主循环
4005d2: 7e f6 jle 4005ca <plus+0x1c> # 比较结果不成立则跳转至4005b9 主循环 for (i = ; i < 10; ++i) # for (i = 0; i < 10; ++i)
4005d4: c7 fc movl $0x0,-0x4(%rbp) # i =
4005db: eb jmp 4005e1 <plus+0x33> # 跳转至4005e1
4005dd: fc addl $0x1,-0x4(%rbp) # i = i + 主循环
4005e1: 7d fc cmpl $0x9,-0x4(%rbp) # i与9比较 主循环
4005e5: 7e f6 jle 4005dd <plus+0x2f> # 比较结果不成立则跳转至4005dd 主循环
;
}

可以从汇编代码得出如下表格

  while主循环语句数

do...while主循环语句数

for主循环语句数
i-- 5 5 3
--i 3 3 3
i++ 5 5 3
++i 3 3 3

小结

  可以从表中得出结论:循环效率最高也需要执行3条汇编语句,而最慢需要5条汇编语句,使用i--和i++进行循环控制时,不同的循环结构所对应的汇编代码量不同,最少的为for循环,只需要3条汇编指令,最多的为while循环,需要5条汇编指令,而当使用--i和++i进行循环控制时,无论哪一种循环结构执行效率都一样是最优的,都只需要3条代码,而无论使用i--,--i,i++,++i中哪一种,for循环的效率应该是最高的,都只用了3条汇编代码。

关于for,while,dowhile效率测试的更多相关文章

  1. NHibernate Demo 和 效率测试

    本文关于NHibernate的Demo和效率测试,希望对大家有用. 1.先去官网下载Nhibernate 2.放入到项目中并建立Helper类 private static ISession _Ses ...

  2. 关于 pgsql 数据库json几个函数用法的效率测试

    关于 pgsql 数据库json几个函数用法的效率测试 关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次 ...

  3. Python_线程、线程效率测试、数据隔离测试、主线程和子线程

    0.进程中的概念 三状态:就绪.运行.阻塞 就绪(Ready):当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态成为就绪状态. 执行/运行(Running)状态:当 ...

  4. 进程池原理及效率测试Pool

    为什么会有进程池的概念? 当我们开启50个进程让他们都将100这个数减1次减到50,你会发现特别慢! 效率问题,原因: 1,开辟内存空间.因为每开启一个进程,都会开启一个属于这个进程池的内存空间,因为 ...

  5. postgresql-int,bigint,numeric效率测试

    在postgresql9.5的时候做过一个测试就是sum()的效率最终的测试结果是sum(int)>sum(numeric)>sum(bigint)当时比较诧异为啥sum(bigint)效 ...

  6. ORM for Net主流框架汇总与效率测试

    框架已经被越来越多的人所关注与使用了,今天我们就来研究一下net方面的几个主流ORM框架,以及它们的效率测试(可能会有遗漏欢迎大家讨论). ORM框架:Object/Relation Mapping( ...

  7. 纯PHP Codeigniter(CI) ThinkPHP效率测试

    最近一直想做一个技术类的新闻站点,想做的执行效率高些,想用PHP做,一直纠结于用纯PHP做还是用CI或者THINKPHP.用纯PHP效率高,缺点 n多,比如安全方面.构架方面等等等等:用CI.thin ...

  8. Python--day39--进程池原理及效率测试

    #为什么要有进程池的概念 #效率 #每次开启进程都要创建一个属于这个进程的内存空间 #寄存器 堆栈 文件 #进程过多 操作系统调度进程 # #进程池 #python中的 先创建一个属于进程的池子 #这 ...

  9. 关于pgsql 几个操作符的效率测试比较

    关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次取平均时间.测试结果:->> 效率高 5% ...

随机推荐

  1. canvas-0scale.html

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  2. STOMP

    STOMP: 说明:STOMP is a simple text-orientated messaging protocol. 面向文本消息协议 spring 之stomp https://www.c ...

  3. ORM&MySQL

    概念: ORM:对象关系映射 , 全拼 Object-Relation Mapping ,是一种为了解决面向对象与关系数据库存在的互不匹配现象的技术.主要实现模型对象到关系型数据库数据的映射.比如:把 ...

  4. 【转】PHP 杂谈 坑爹的file_exists

    转自:http://www.cnblogs.com/baochuan/archive/2012/05/06/2445822.html 介绍   我发现了一个问题,今天与大家分享.我把整个过程描述一下. ...

  5. 遇到npm报错read ECONNRESET怎么办

    遇到npm 像弱智一样报错怎么办 read ECONNRESET This is most likely not a problem with npm itselft 'proxy' config i ...

  6. python 定时修改数据库

    当需要定时修改数据库时,一般我们都选择起一个定时进程去改库.如果将这种定时任务写入业务中,写成一个接口呢,定时进程显得有些不太合适?如果需要定时修改100次数据库,常规做法会启动100个进程,虽然这种 ...

  7. 转:SQL Server - 使用 Merge 语句实现表数据之间的对比同步

    表数据之间的同步有很多种实现方式,比如删除然后重新 INSERT,或者写一些其它的分支条件判断再加以 INSERT 或者 UPDATE 等.包括在 SSIS Package 中也可以通过 Lookup ...

  8. StartUML用法

    转载地址  http://blog.csdn.NET/tianhai110 (下面参考了原博主的内容,也加入自己的内容,为了自己脑补,也方便其他看到的人脑补) 使用StartUML绘制用例图:     ...

  9. sql2008和sql2012混合安装后打开SQL Server 配置管理器查看出现“远程过程调用失败”0x800706be

    sql2008和sql2012混合安装后打开SQL Server 配置管理器SQL Server服务出现“远程过程调用失败”0x800706be 网上很多人都说这个解决方案,通过卸载“Microsof ...

  10. The Art of Unit Testing With Examples in .NET

    The Art of Unit Testing With Examples in .NET