引言

  大家都知道每种循环对应的效率是不同的,书中都说在循环中使用减法的效率是比加法的效率高的,具体情况是怎么样,我们将详细列出各循环的执行效率问题。本文通过查看汇编代码比较各循环的效率以及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. echarts环形图,自定义说明文字

    一.代码 app.title = '已安装通讯盒电站统计'; option = { backgroundColor: '#0f0f31',//#0f0f31 title: { show:true, x ...

  2. kubectl 常用命令总结

    # 查看所有 pod 列表, -n 后跟 namespace, 查看指定的命名空间 kubectl get pod kubectl get pod -n kube # 查看 RC 和 service ...

  3. 【20190123】JavaScript-轮播图特效中出现的问题

    使用纯html和JavaScript实现焦点轮播图特效,本来之前用setInterval()函数写的一个简单的循环轮播图,但是出现了两个问题:   1. 当网页被切换时,也就是网页失去焦点时,计时器函 ...

  4. html学习笔记——ife task0001

    花了两三天大概看完html和css基本用法,但到自己布局的时候还是很懵不知道从哪里入手啊,就找了个简单的任务(ife2015 spring)试一下. 之前不涉及到布局的跳过,从涉及到position和 ...

  5. Fiddler抓包使用教程-QuickExec

    转载请标明出处:http://blog.csdn.net/zhaoyanjun6/article/details/73468287 本文出自[赵彦军的博客] 在 Fiddler 中自带了一个 Quic ...

  6. 软件工程-CMM与CMMI

    CMM CMMI

  7. 如何创建和还原SQL Server 2005数据库?

    在还原SQL Server 2005数据库文件之前,建议先把要还原的数据库文件复制粘贴到某个盘的根目录下,这样便于一会儿找到相关的文件,比如C盘. 先打开SQL Server 2005的Microso ...

  8. Chrome 如何让光标快速定位到地址栏-进行搜索

    我们经常花费大量的时间来进行使用浏览器搜索网页,如何进行高效的搜索,需要掌握一些快捷键: Windows: Ctrl + L 或 Alt + D 或 F6 Mac: Command + L Linux ...

  9. MySQL面试题之如何优化一条有问题的SQL语句?

    如何优化一条有问题的sql语句? 针对sql语句的优化.我们可以从如下几个角度去分析 回归到表的设计层面,数据类型选择是否合理 大表碎片的整理是否完善 表的统计信息,是不是准确的 审查表的执行计划,判 ...

  10. ping 127.0.0.1和ping本地ip分别测试什么?

    ping 127.0.0.1 是你本地的回环地址! 实际上只要是127.0.0.1到127.255.255.255都是回环地址!都是可以PING检查的! 它能ping通,说明你的TCP/IP协议栈没问 ...