关于for,while,dowhile效率测试
引言
大家都知道每种循环对应的效率是不同的,书中都说在循环中使用减法的效率是比加法的效率高的,具体情况是怎么样,我们将详细列出各循环的执行效率问题。本文通过查看汇编代码比较各循环的效率以及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效率测试的更多相关文章
- NHibernate Demo 和 效率测试
本文关于NHibernate的Demo和效率测试,希望对大家有用. 1.先去官网下载Nhibernate 2.放入到项目中并建立Helper类 private static ISession _Ses ...
- 关于 pgsql 数据库json几个函数用法的效率测试
关于 pgsql 数据库json几个函数用法的效率测试 关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次 ...
- Python_线程、线程效率测试、数据隔离测试、主线程和子线程
0.进程中的概念 三状态:就绪.运行.阻塞 就绪(Ready):当进程已分配到除CPU以外的所有必要资源,只要获得处理机便可立即执行,这时的进程状态成为就绪状态. 执行/运行(Running)状态:当 ...
- 进程池原理及效率测试Pool
为什么会有进程池的概念? 当我们开启50个进程让他们都将100这个数减1次减到50,你会发现特别慢! 效率问题,原因: 1,开辟内存空间.因为每开启一个进程,都会开启一个属于这个进程池的内存空间,因为 ...
- postgresql-int,bigint,numeric效率测试
在postgresql9.5的时候做过一个测试就是sum()的效率最终的测试结果是sum(int)>sum(numeric)>sum(bigint)当时比较诧异为啥sum(bigint)效 ...
- ORM for Net主流框架汇总与效率测试
框架已经被越来越多的人所关注与使用了,今天我们就来研究一下net方面的几个主流ORM框架,以及它们的效率测试(可能会有遗漏欢迎大家讨论). ORM框架:Object/Relation Mapping( ...
- 纯PHP Codeigniter(CI) ThinkPHP效率测试
最近一直想做一个技术类的新闻站点,想做的执行效率高些,想用PHP做,一直纠结于用纯PHP做还是用CI或者THINKPHP.用纯PHP效率高,缺点 n多,比如安全方面.构架方面等等等等:用CI.thin ...
- Python--day39--进程池原理及效率测试
#为什么要有进程池的概念 #效率 #每次开启进程都要创建一个属于这个进程的内存空间 #寄存器 堆栈 文件 #进程过多 操作系统调度进程 # #进程池 #python中的 先创建一个属于进程的池子 #这 ...
- 关于pgsql 几个操作符的效率测试比较
关于pgsql 几个操作符的效率测试比较1. json::->> 和 ->> 测试方法:单次运行100次,运行10个单次取平均时间.测试结果:->> 效率高 5% ...
随机推荐
- deepin使用笔记-解决安装并解决gvim没有启动器的问题
我的邮箱地址:zytrenren@163.com欢迎大家交流学习纠错! 1.安装gvim #apt-get install vim-gtk3 2.创建桌面启动器 创建/usr/share/applic ...
- demo:复制粘贴功能
复制链接功能,也是为了方便用户一键"复制",粘贴链接和文本到指定位置,在此,接着上一篇"demo:生成专属二维码link "来记录一键"复制" ...
- Java抽象类和接口的比较
一个软件设计的好坏,我想很大程度上取决于它的整体架构,而这个整体架构其实就是你对整个宏观商业业务的抽象框架,当代表业务逻辑的高层抽象层结构 合理时,你底层的具体实现需要考虑的就仅仅是一些算法和一些具体 ...
- 【转】ASP.NET Core 依赖注入
DI在.NET Core里面被提到了一个非常重要的位置, 这篇文章主要再给大家普及一下关于依赖注入的概念,身边有工作六七年的同事还个东西搞不清楚.另外再介绍一下.NET Core的DI实现以及对实例 ...
- javascript打印1-100内的质数
<script> /* 质数定义: 质数(prime number)又称素数,有无限个. 质数定义为在大于1的自然数中,除了1和它本身以外不再有其他因数. 1不是质数 */ //声明变量 ...
- 使用 PsPing & PaPing 进行 TCP 端口连通性测试
PsPing & PaPing 介绍 通常,我们测试数据包能否通过 IP 协议到达特定主机时,都习惯使用 ping 命令.工作时 ping 向目标主机发送一个 IMCP Echo 请求的数据包 ...
- Dos烧录脚本
Dos命令之前更改的太简单,现在加入判断是否进入fasboot模式和判断Android镜像是否存在:代码已经尽量简化成这样,dos命令功能还是比较不好用的,用了一下午的时间... @echo off ...
- ES6 入门
1.简介 ECMAScript 6.0 是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了.它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序, ...
- weblogic CVE-2018-2628漏洞利用工具
weblogic CVE-2018-2628漏洞利用 漏洞环境: Windows2018R2 weblogic10.3.6 漏洞利用过程: 搭建好存在CVE-2018-2628漏洞的weblogic平 ...
- PLSQL操作Oracle创建用户和表
1.打开PLSQL,填写用户名和密码(初始有两个用户sys和system,密码是自己安装oracle数据库时定的),Database选择ORCL(默认数据库,oracle中创建的用户就像是mysql中 ...